Stories
Slash Boxes
Comments

SoylentNews is people

SoylentNews is powered by your submissions, so send in your scoop. Only 13 submissions in the queue.
posted by Fnord666 on Monday July 03 2017, @10:12PM   Printer-friendly
from the it's-a-feature dept.

Submitted via IRC for TheMightyBuzzard

A bug in Linux's systemd init system causes root permissions to be given to services associated with invalid usernames, and while this could pose a security risk, exploitation is not an easy task.

A developer who uses the online moniker "mapleray" last week discovered a problem related to systemd unit files, the configuration files used to describe resources and their behavior. Mapleray noticed that a systemd unit file containing an invalid username – one that starts with a digit (e.g. "0day") – will initiate the targeted process with root privileges instead of regular user privileges.

Systemd is designed not to allow usernames that start with a numeric character, but Red Hat, CentOS and other Linux distributions do allow such usernames.

"It's systemd's parsing of the User= parameter that determines the naming doesn't follow a set of conventions, and decides to fall back to its default value, root," explained developer Mattias Geniar.

While this sounds like it could be leveraged to obtain root privileges on any Linux installation using systemd, exploiting the bug in an attack is not an easy task. Geniar pointed out that the attacker needs root privileges in the first place to edit the systemd unit file and use it.

[...] Systemd developers have classified this issue as "not-a-bug" and they apparently don't plan on fixing it. Linux users are divided on the matter – some believe this is a vulnerability that could pose a serious security risk, while others agree that a fix is not necessary.

See, this is why we can't have nice init systems.

Source: http://www.securityweek.com/linux-systemd-gives-root-privileges-invalid-usernames


Original Submission

 
This discussion has been archived. No new comments can be posted.
Display Options Threshold/Breakthrough Mark All as Read Mark All as Unread
The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
1 (2)
  • (Score: 4, Insightful) by Lagg on Tuesday July 04 2017, @05:52AM (3 children)

    by Lagg (105) on Tuesday July 04 2017, @05:52AM (#534692) Homepage Journal

    Every time shit like this comes up that Lennart or someone else that can't really deal with criticism calls "not a bug" and closes my love for the good parts of systemd decrements.

    Also I won't pretend to understand in what universe this could make root the fallback (attempt to deal with UID-passed values, var initialized to 0 pre-parse instead of null, not checked?) but this is why you don't assume things about input before you're done parsing.

    Seriously though I'm sick of Lennart's shit [github.com]. The excuse of the introvert being unfairly criticized only goes so far.

    By the way looks like my guess above was correct [github.com]. Fuckin nailed it breh. (see uint32_t uid initializer value)

    --
    http://lagg.me [lagg.me] 🗿
    • (Score: 0) by Anonymous Coward on Tuesday July 04 2017, @06:53AM

      by Anonymous Coward on Tuesday July 04 2017, @06:53AM (#534699)

      "--systemdLove" looks like a command line option.

      (see uint32_t uid initializer value)

      How ironic, UID_INVALID [github.com] is mentioned only 11 lines previous.

    • (Score: 2) by ledow on Tuesday July 04 2017, @08:21AM (1 child)

      by ledow (5567) on Tuesday July 04 2017, @08:21AM (#534729) Homepage

      Anyone with a brain would separate things out, though.

      "Did we see a valid username yet?" variable (literally binary).
      "What is the username that we saw" (string).

      Then, even if you parse through the whole file, you would test against the "Did we see a valid username" variable and error if you haven't (or fallback to a safe default).

      Using the string itself directly (i.e. is it NULL), is a very silly thing to do given the number of string-parsing problems you could encounter along the way, and using its default value (surely it should always be made NULL until otherwise initialised) directly would be pretty ludicrous (I don't expect that's what systemd actually does, by the way).

      The problem is that you can't fix design in hindsight - how many other syntax errors, string-parsing problems, or line-break issues or whatever could result in the username being obscured to the program to the extent that it just falls back to root? It's just stupid.

      • (Score: 2) by Jesus_666 on Tuesday July 04 2017, @05:42PM

        by Jesus_666 (3044) on Tuesday July 04 2017, @05:42PM (#534852)
        From what I've heard that's what they do - it's just that the default assumption (if no User= line is present) is that the unit runs as root. If they do have a User= line and don't like its contents, however, they seem to pretend it wasn't there in the first place instead of refusing to run the unit.
  • (Score: 2) by ledow on Tuesday July 04 2017, @08:14AM

    by ledow (5567) on Tuesday July 04 2017, @08:14AM (#534723) Homepage

    Mistakes happen. But that also means we should plan for mistakes happening. A mistake in a unit file shouldn't result in root. In fact, it's hard to imagine why anything in a unit file should result in root rather than a separate user for each one entirely.

    This is an example of poor design, which you can't fix with patches. Nobody has considered what the fallback, escape route, error path, etc. is, and it ends up as being root.

  • (Score: 1) by pTamok on Tuesday July 04 2017, @11:15AM (4 children)

    by pTamok (3042) on Tuesday July 04 2017, @11:15AM (#534762)

    Part of the issue here is the differences in opinion of what constitutes a valid username. Are leading digits allowed or not?
    Similarly, should the code in question check if the username is actually present on the system it is being executed on, as a username can be valid, but non-existent on the system.
    As I understand it, in either of the above cases, the code defaults to running as root.

    Now, I am not a Linux programmer, so I don't know if there is a standard routine available for checking the validity of a username, or even if a generally agreed upon standard exists. Either way, I don't think is is correct for code that does not have a major function of username processing to implement its own idiosyncratic standard for username validity. At the very least, I would expect the code to check if the username requested actually exists on the system (I understand some might see this as a security breach*) - because in such a case, if the username exists, you can probably fairly safely assume that it is regarded as valid by the rest of the system.

    *The obvious approach is to call a function, offering a username and returning a flag to say of that username is present in /etc/passwd (for added fun, also check that the given username is in a group allowed to run the desired script). The obviously obvious brain dead approach of allowing read-only access to the entire /etc/passwd and searching it yourself, while tempting for neophytes, would be silly. By checking usernames one at a time against the oracle, rather than just reading the file, it makes exploiting the function to get a list of usernames time-consuming.

    • (Score: 2) by ledow on Tuesday July 04 2017, @11:40AM (2 children)

      by ledow (5567) on Tuesday July 04 2017, @11:40AM (#534767) Homepage

      The problem is also one of username mapping. Just because you're fredbloggs on one machine doesn't mean you're allowed access to anything of fredbloggs on another that happens to have the same username. Do you go by username, or by user ID (which can be mapped differently but it was is encoded on the filesystem for permissions).

      At minimum, checking the username is valid using a standardised piece of library code is a no-brainer, rather than making up your own rules.

      But just because a specified username exists or not, and acting in a poor way after that point, is just terrible. Why would you do that? Error and fail, or carry on if you're happy as the specified user.

      It reeks of "coding for convenience", where if you move a systemd install that doesn't end up on a machine with the right packages/user, rather than error, it just ignores it and carries on as root.

      This reinvention-and-redefinition of the wheel is the main reason that something huge, monolithic, and with so many fingers in so many pies, like systemd does, is stupendously bad.

      • (Score: 2) by Justin Case on Tuesday July 04 2017, @02:59PM (1 child)

        by Justin Case (4239) on Tuesday July 04 2017, @02:59PM (#534806) Journal

        (Grandparent)

        what constitutes a valid username

        (Parent)

        checking the username is valid using a standardised piece of library code is a no-brainer

        If the user ID exists it is evidently valid. That decision has been made by the creating-user-ID-thingy. Why would you expect to re-implement that logic elsewhere, to gain nothing?

        If the user ID doesn't exist you probably don't want to go spinning up processes under that ID.

        So all that is needed is to check if the supplied string is an existing user.

        • (Score: 2) by PocketSizeSUn on Tuesday July 04 2017, @08:42PM

          by PocketSizeSUn (5340) on Tuesday July 04 2017, @08:42PM (#534923)

          man 3 getpwnam_r

          CONFORMING TO
                        POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD. The pw_gecos field is not specified in POSIX, but is present on
                        most implementations.

          NOTE
                        The user password database mostly refers to /etc/passwd. However, with recent systems it also refers to net‐
                        work wide databases using NIS, LDAP and other local files as configured in /etc/nsswitch.conf.

    • (Score: 2) by rleigh on Thursday July 06 2017, @07:28AM

      by rleigh (4887) on Thursday July 06 2017, @07:28AM (#535614) Homepage

      The only thing a programmer needs to do is call getpwnam: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getpwnam.html [opengroup.org] an if it returns a value, it's valid.

      systemd's problem is also trying to set policy. Plus some awful noddy bugs. Naming policy could come from the local admin or your sidewide LDAP/AD. It's way out of scope for systemd.

  • (Score: 0) by Anonymous Coward on Tuesday July 04 2017, @12:02PM

    by Anonymous Coward on Tuesday July 04 2017, @12:02PM (#534769)

    i dont get it.

    fast forward, 5 years, this "non-bug" is old news, thus forgotten.
    along comes a newbie , blue-and-green from all the windows beating, decides "enough is enough" and starts to learn/play with linux.

    obviously it's his linux system and sooner or latter s/he will create a user.
    because usernames starting with a digit sound "l33t", that's what gets created ... WAMM-BUMMM!

    without having ANYTHING warning this novice abused ex-windows user about this secret pitfall, the next day s/he is pawned, because
    his LAMP is running as the "1337web" user ...

  • (Score: 2) by butthurt on Tuesday July 04 2017, @11:26PM (2 children)

    by butthurt (6141) on Tuesday July 04 2017, @11:26PM (#534971) Journal

    Many user management tools accept either user names or UID’s as arguments.

    chown is one tool that accepts either user names or UID’s.

    This makes root the owner of example.txt:

    chown 0 example.txt

    Having a non-privileged user with the user name zero would be very dangerous.

    -- http://paulgorman.org/technical/presentations/linux_username_conventions.pdf [paulgorman.org]

    • (Score: 1, Insightful) by Anonymous Coward on Wednesday July 05 2017, @09:29AM (1 child)

      by Anonymous Coward on Wednesday July 05 2017, @09:29AM (#535117)

      Usernames starting with digits are not the same as numeric user names. Numeric user names would be user names that entirely consist of digits.

      That's not unlike the fact that 123.com is a valid domain name, while 127.0.0.1 is not.

      • (Score: 2) by butthurt on Thursday July 06 2017, @12:25AM

        by butthurt (6141) on Thursday July 06 2017, @12:25AM (#535469) Journal

        A username consisting entirely of digits begins with a digit, doesn't it? Numeric usernames are a subset of the usernames which begin with digits. The given example, a username of "0", is a valid username. However, the essay I linked discourages such usernames. On the same page (page 14) it discourages usernames which begin with a digit but contain other characters--which, according to POSIX, can also be valid. Instead of commenting about those, I commented about purely numeric usernames because the reason for the essay's recommendation against purely numeric usernames is easier to understand.

1 (2)