Hacker News new | ask | show | jobs
by krnlpnc 1376 days ago
Let’s move the linux kernel and sshd into systemd while we’re at it
4 comments

You're joking, but I'm 100% serious.

PAM is crusty and has a bad architecture. The fact that it's written in C, and is linked into another program as a library makes it impossible to fully isolate it from its host application, and exposes it to a myriad possible exploit points.

Even wrapper binaries are not a great idea because of how UNIX works.

fork() + exec() means the executed binary inherits a lot of state from the caller. Open files, signals, environment variables, chroot, mlock, resource limits, seccomp... there's a myriad of mechanisms that an executed binary can be exposed to, and even if it somehow perfectly takes all of them into account and defends itself against any possible malicious manipulation, the next kernel version could add a new one.

That's why I think a sane, modern version of PAM should be a service and only communicate via a UNIX socket. That way you vastly reduce the attack surface, and allow locking up the PAM bits into their own, well defended box.

"The fact that it's written in C"

The calling convention is C, but you can write PAM in any language.

"and is linked into another program as a library makes it impossible to fully isolate it from its host application"

Huh? You can never isolate the client side code. You will always have something in your app.

"I think a sane, modern version of PAM should be a service and only communicate via a UNIX socket."

So, write a module that talks to a socket. That's how like half of the PAM modules already operate. You will always have to have code in the application to talk to whatever oracle you're using. What you're describing here isn't any different from how PAM already works.

> Huh? You can never isolate the client side code. You will always have something in your app.

Yes, and that "something" can be reduced to reads and writes to a socket.

> So, write a module that talks to a socket. That's how like half of the PAM modules already operate.

I mean move all of PAM to a service. So for instance currently chsh is a setuid application because it needs to be able to write to /etc/passwd. This is a requirement because the way it works is that it links to libpam, which will load a module, which will write to /etc/passwd, all inside the 'chsh' program.

My suggestion would result in chsh becoming a completely unprivileged application that only deals with interfacing with the user, then passes the action to pamd, which would run with the required privileges.

"Yes, and that "something" can be reduced to reads and writes to a socket."

Yes, and as I said that is already what most PAM modules do. That is how most things work today.

"I mean move all of PAM to a service."

I think you don't understand what PAM is.

"which will load a module, which will write to /etc/passwd"

No, this isn't how PAM works at all. PAM modules don't write to /etc/password. They just authenticate. They do not (necessarily) need root privileges.

"My suggestion would result in chsh becoming a completely unprivileged application that only deals with interfacing with the user, then passes the action to pamd, which would run with the required privileges. "

You have the way PAM and chsh works entirely backwards. Here's how it actually works:

1) chsh runs as root only because chsh itself needs to modify system files. This has nothing to do with PAM, and is optional (see below)

2) chsh calls pam_auth("chsh",...) to authenticate the current user, if the current user isn't really root. This is PAM's ONLY involvement.

3) chsh then directly edits /etc/passwd itself[1]. Totally unrelated to PAM. If you're on a system with directory services instead of local files, then chsh needs to change those directory services instead (and, as such, doesn't need to run as root - though it will need to authenticate to the directory service)

In summary, your ideas aren't bad - it's just that they're how things already work. Most PAM modules are already just talking to a socket somewhere. They don't do the other things you seem to think they do.

[1] https://github.com/mmalecki/util-linux/blob/master/login-uti...

For completeness it's worth mentioning that chsh calls into pam with pam_acct_mgmt and pam_open_session/pam_close_session after it's authenticated the user with pam_auth.
You should look into GNU Hurd then.

I'm being serious, as exactly what you're describing sounds an awful lot like their micro-kernel approach. At least as of the last time I looked into it.

Your problem description isn't what I disagree with, it is your solution.
This sort of already exists in the form of sssd. In particular, pam_ssd.so connects to sssd's PAM responder & acts as a dumb client library to the authentication logic within the sssd process.
> fork() + exec() means the executed binary inherits a lot of state from the caller.

Does Linux have process spawning that doesn't have this problem?

Merely another part of the complete systemd/Linux operating system? ;)
I think you mean GNU/systemd!
Don't give them ideas, some take systemd-unikernel very seriously.
See your kernel; raise you the whole data center.