Article can be summarized: "I didn't knew much about PAM, had random assumption and wasted a bit of time in the process". Not much of the substance unfortunately.
Yeah I was pretty disappointed, was hoping for something more. Most of the problems the author ran into had nothing to do with PAM. Things like "distributions compile PAM without debug logging" (annoying but common) and "PAM is a plugin system, so setting breakpoints is hard because dlsym() is used" (how else would you implement a plugin system in C, without requiring build-time foreknowledge of every plugin that exists?) and then some misconception that this is a "Java kind of thing" because Sun did it (when libdl predates Java and is by no means a Sun-specific thing, even though it was indeed first seen in SunOS).
It just felt like reading about someone who hasn't used C all that much, digging into a C-based project and discovering how some not-particularly-esoteric things are usually done in C ("function pointers aren't type-safe!") and then being surprised... and disgusted in a pretty "language elitist" way.
PAM is by no means an amazing piece of software. It has some baked-in assumptions that made sense 30 years ago that maybe don't so much these days. And it could be designed in a way that's more secure (though I expect you could reimplement PAM with better isolation while still keeping the API and flexibility). But it's... surprisingly not that bad, considering its age.
I was really hoping for something that actually explained the history behind PAM and why it is the way it is, because PAM doesn't really make a whole heck of a lot of sense - usually when that's the case, understanding the context it was developed in goes a long way to explaining why it was done the way it was. Definitely not what this article was, though.
How can you "know much about PAM", though, other than getting very familiar with source code of PAM, the PAM modules and poorly-documented distro conventions? As the article mention, documentation is scarce, and I cannot agree more.
The article is at least showing how bad the situation is. I am rather familiar with various other aspects of Linux system administration, but PAM is a dark corner to me.
I found parts of it interesting, but I couldn't tell why the author [edited] was ascribing so many issues to be PAM's fault. Debugging dynamically loaded libraries, for example. Many things use dynamically loaded libraries, and it's not surprising PAM does so, given the need to be "pluggable".
Somehow that's worse. Is it really that hard to call someone "they"? Please excuse my bluntness, but this is an English language construct that's existed since Beowulf (an epic poem that predates even Middle English). Saying '[edited out "he"]' looks like you are invalidating my own view of my identity. I have to deal with enough of this already. Why do you feel you need to add to the pile? What have I done to deserve such treatment?
Right, I made a mistake, fixed it, tagged with [edited out "he"] so it wasn't a stealth edit. Now re-edited to just say [edited], since that's also causing unintended issues.
I'm not trying to invalidate anything, had no idea of the background. It was just a mistake, nothing more.
Years ago, I’ve found an inverse correlation between emoji frequency and information quality. Anime is usually indicative as well, as is excessive use of imagery in general. All together are a dead give-away.
20'ish years ago I remember the original author of the `pam_realm` PAM module [0] writing the module becase "it was easier to work around PAM, than to understand what the fuck was happening inside of PAM".
The format of the article, and it's unwillingless to go to the point made me quit reading half way. Even in reader mode the flow of reading is interrupted every 2 lines by a large useless image or some snarky comment from the author.
Looks like I missed a sed command or two. I usually write out "underscore" in the script so I read it literally during recording: https://i.imgur.com/j3RdHA5.png
I write out punctuation like underscore so that I know that is what I am literally saying to the camera. I usually edit that out. Apparently I missed out on that this time. Oops! Sorry. I'll put that on the checklist for next time (half considering making tests fail if I forget to do it).
Of all your pictures the actual useful ones are three:
Drawbacks of PAM
Lessons Learned
Credits
Presentation != blog post. Different formats. I could read that only after sticking the browser to the side of the screen with 25% width and reader mode. Reading your post on the desktop is like trying to watch a 10-minute episode interrupted for an ad every 10 seconds.
Perhaps you can split your 'visual aids' to 'essential' (liek those three I listed up there) and 'non-essential', which could be skipped in the blog post.
At least with this I can work out what your primary points are. The most important takeaway seems to be that OpenSSH sshd doesn't really use PAM unless you enable "ChallengeResponseAuth" config option, so if you want your custom PAM module to work with sshd, you need to turn that on.
Another important point you make is, on Ubuntu, you need to download the debug symbol packages for systems libraries if you want gdb to give you meaningful backtraces.
The suggestion of putting a breakpoint on dlsym also seems helpful.
This meme-laden presentation style, I seem totally incapable of consuming or producing it, and I don't really get it. I don't know if it is a generational thing or something.
For reference, I liked your format. It was different and fun. Every highly technical conference would be infinitely more fun if all speakers were given an avatar like that haha. I especially loved the graphic with Anya pointing at Anya pointing at Anya :thumbsup: .
It was obvious you were going for an entertainment format rather than merely cramming as much information in as tight a space as possible (which is typical for 'conf talks). Hacker News geeks probably aren't the ideal judges for that sort of thing. As a member of this group most of us have forgotten what it means to "not be super busy" all the time and being "forced" to watch something highly technical slowed down into an entertainment-focused story telling format can feel wrong and a little frustrating. Just know that there's at least a few people out there that appreciated it :)
It's a presentation in blog form. The images are the slides from presentation, the text is what Xe says. Perhaps you don't like this style of presentation?
PAM should be a service that communicates over an UNIX socket. Upsides:
* You can completely isolate it from anything else. Lock it into a sandbox. Use SELinux to ensure it doesn't do anything weird.
* Much more secure -- you have a very narrow communication channel, and no exposure to stuff like LD_PRELOAD.
* You avoid the mess of the above for the applications using it. Apps using PAM execute PAM code, and that means that anything that uses PAM needs to be able to do any arbitrary thing a PAM module might want to do.
* Applications using PAM no longer need to have root access. Your screensaver/lock screen can be completely unprivileged.
* If it can be an UNIX socket, it probably can also be a TCP socket, so you can have it run remotely if such a thing makes sense.
* The protocol can be inspected
* Good opportunity for updating the API and fixing anything lacking.
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 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.
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.
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.
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.
> You can completely isolate it from anything else. Lock it into a sandbox. Use SELinux to ensure it doesn't do anything weird.
You don't need systemd for that, as it stands not having a running process means no need for a sandbox. You created the problem you are solving. Even if it needed a standalone process you don't need systemd to sandbox it.
> Much more secure -- you have a very narrow communication channel, and no exposure to stuff like LD_PRELOAD.
Fix the root cause: LD_PRELOAD.
> You avoid the mess of the above for the applications using it. Apps using PAM execute PAM code, and that means that anything that uses PAM needs to be able to do any arbitrary thing a PAM module might want to do.
Ok you lost me here. Any reason a new PAM can't have solid api boundaries and capability restrictions?
> Applications using PAM no longer need to have root access. Your screensaver/lock screen can be completely unprivileged.
You should always drop privilege after getting whatever handle you need anyways but this is would be great but my wish would be to have specific linux capabilities to solve this if they don't exist already.
> If it can be an UNIX socket, it probably can also be a TCP socket, so you can have it run remotely if such a thing makes sense.
TCP adds a magnitude of complexity, people leaving PAM exposed to the internet would be a thing. You expanded PAM to also solve SSH (which uses PAM now lol)?
> The protocol can be inspected
Uhhh... gdb?
> Good opportunity for updating the API and fixing anything lacking.
And breaking all sorts of compatibility, adding all kinds of complexity and forcing many users to forcibly pull out all the hair on their heads in frustration.
"I can't login because of newpam, let me tcpdump it, decrypt it and see if it is iptables, routing issues, dns issues, app config; nope all of that is good it must me the remote end"
Not very fun on top of already complex AAA policy definitions you will need.
Complex solutions are bad solutions, simple solutions are ideal solutions.
I think you know that but perhaps what you know and are comfortable with seems simple to you?
That said I think Windows' modern VBS lsass is a good role model if it goes this way.
I agree with your post but I wanted to chime in that LD_PRELOAD isn't even a problem in this scenario! If you're running code as you then the permissions model assumes you can modify/control it. Always. Whether by LD_PRELOAD, or by a debugging interface such as ptrace(2). Or just by copying the binary, modifying it and running that instead.
We already disable things like LD_PRELOAD or ptrace(2) for setuid scenarios, so again there's no issue.
> "You should always drop privilege after getting whatever handle you need"
Wanted to chime in here too. PAM doesn't require root -- the initial assumption is wrong. You can't just drop privileges in a PAM module though, because it's a function running in the application proper so any process-global state change would impact the calling process.
What you can do (and what some PAM modules I've written actually do) when invoked as root is you can seteuid() to a non-root user as long as you're sure to seteuid(0) back to root before returning from your module.
> "TCP adds a magnitude of complexity"
Erm, so most PAM modules already do this. This is how pam_ldap, pam_kerberos, etc all work. No big deal. But it also doesn't need to be changed.
Honestly, there is a real need for a service for updating local directory files like /etc/passwd. It's very stupid that we have individual binaries with ad-hoc C code editing /etc/passwd in 2022. But the right solution is something generic and modular more akin to a local ldap instance -- not reinventing the wheel with friggin' systemd.
For most of what you said, you are right and I didn't know that, but that doesn't contradict my opposition to the original argument, you just have a better and more correct reasoning.
That said, perimeter based security is dead, as in 2000's dead. There is no such thing as "if you control _____ we assume _____". No, unless explicit permission is granted by the thing controlling information, permission is denied. This could be accessing a file (basic unix acls will do) or connecting to a network service (e.g.: mtls). With LD_PRELOAD and ptrace() an explicit permissin isn't granted to the debugger by the specific debugee therfore regardless of who the user is or file acls permission must be denied. Even search order hjacking (I am only familiar with windows dlls not .so's for the record) is a vulnerability even if it is the same user running it because it can be used by threat actors for devious reasons. Especially global ld_preloading, that just has to go away. Find another way, look at macos!!
> What you can do (and what some PAM modules I've written actually do) when invoked as root is you can seteuid() to a non-root user as long as you're sure to seteuid(0) back to root before returning from your module.
Isn't that what I said by "drop privilege"? I've only used pam_exec so I never had to deal with this with pam but in general when I need root, I get whatever api handle, socket,etc.... and change uid/gid to a low-priv user.
> Erm, so most PAM modules already do this. This is how pam_ldap, pam_kerberos, etc all work. No big deal. But it also doesn't need to be changed.
Yes, some PAM modules, that's why it is modular as opposed to the suggestion I wad disagreeing with which is having one process that does TCP and everything else you can think of and that's fine because sandbox. You can write simple pam modules or complex ones with TCP, custom protocol,etc... and that marvelous modular architecture is not faulty and should not be replaced by a giant complex systemd process.
Right, we agree! I'm just adding some more information.
> "With LD_PRELOAD and ptrace() an explicit permissin isn't granted to the debugger by the specific debugee therfore regardless of who the user is or file acls permission must be denied. "
Explicit permission is in fact granted because they are running as the same user. There is a permission check on attaching gdb which is using ptrace(2).
Regarding LD_PRELOAD or other linker instructions, again there is an explicit permissions check: In this case, the permission is the execute permission on the original binary. If you have permission to execute then you can set any linker parameter you wish, or even use a non-system provided linker! There's nothing stopping a user from compiling their own linker and using it to run a system binary, so long as it's running as them and not setuid as another user.
> "Even search order hjacking is a vulnerability even if it is the same user running"
It's not, and this kind of thinking is evidence of a faulty security model.
Linker configuration is just one small aspect of invoking an executable. You can always simply copy and edit the executable instead, as I mentioned in my previous post. Or you can always use your own linker. Or bring your own statically linked binary, with no linking to system libraries at all.
Looking for this kind of thing might be useful as a signal on an otherwise locked-down system (is development happening? Why?), but it has no place in a cohesive permissions model for a general-function workstation. It really cannot be a functional part of a well designed security architecture for a system which allows for software development.
> "Isn't that what I said by "drop privilege"? I've only used pam_exec so I never had to deal with this with pam but in general when I need root, I get whatever api handle, socket,etc.... and change uid/gid to a low-priv user."
Typically "dropping privileges" means setting the ruid (real uid), irrevocably becoming the lower-privilege user. This is the "grab a resource and give up access" model. This can't happen with PAM because it's a function not a separate process and it needs to return holding the same permission state it was called with.
pam_exec would be forking and setting the uid in the child process prior to exec.
In a single process scenario where a function must return with the process state unchanged, the euid (effective uid) can be set to a lower-privilege user. The ruid remains 0, so privileges aren't permanently dropped as they can be restored at any time with a subsequent seteuid(0) call. It's more a temporary lowering of privileges. This is not threadsafe, of course, as privilege is process-global state.
> "and that marvelous modular architecture is not faulty and should not be replaced by a giant complex systemd process. "
The one item I still disagree on is with ptrace and LD_PRELOAD's permission being explicit. It is not, it is implicit just as you described because for both cases their permission is implied because of who owns the process and fs acls. On my Mac for example, I couldn't troubleshoot something in my browser process both as user and root with gdb because the browser's publisher didn't give gdb an explicit permission to debug it but it turns out the "builtin" lldb had permission so I was able to attach and debug.
Implying things because ownership is what I am disagreing with. Basic unix acls give read,write or execute permissions, preloading a shared library or using ptrace to attach to a process is not explicitly defined in the acl, read and write apply to the file, not the process and execute can only be execve,clone,fork and related syscalls.
In an ideal world, in addition to PKI/signatures, ELF headers would contain explicit permissions like this. So, for example, htop/top would disallow LD_PRELOAD and the kernel/LSM would police against permission header tampering without root or LSM-specific credentials even by the owner (ideally not root). This would make a lot of usermode rootkits useless (forcing them to use other means of course). Execute acl only defines the permission to start the program not what others can do to the program during its runtime.
I understand your reasoning, but I still disagree. I'll add a bit more information as to why:
> " It is not, it is implicit just as you described because for both cases their permission is implied because of who owns the process and fs acls. On my Mac for example, I couldn't troubleshoot something in my browser process both as user and root with gdb because the browser's publisher didn't give gdb an explicit permission to debug it but it turns out the "builtin" lldb had permission so I was able to attach and debug."
You're just describing extra permissions in osx - I believe related to code signing. Any system can introduce additional privilege checks (linux has yama/ptrace_scope), but this doesn't change the underlying permissions model.
Furthermore, the permission is absolutely implied and this can be directly demonstrated on linux: You can simply open up /proc/$pid/mem and read/write values into the process's memory. This is sufficient to do anything. All memory can be read from and written to (provided the pages are writeable).
> "preloading a shared library or using ptrace to attach to a process is not explicitly defined in the acl"
It is. Specifically: The executable handler for /bin/ls will be (on my system) /lib64/ld-linux-x86-64.so.2. The explicit ACL is the execute bit on /lib64/ld-linux-x86-64.so.2 (to run that linker with all its options) and the executable /bin/ls (the invoking file). There are also permission checks on all the libraries which will be linked.
You can test this by copying the linker:
cp /lib64/ld-linux-x86-64.so.2 /tmp/mylinker
and then if you like, modifying it and running it explicitly:
/tmp/linker /bin/ls
There are explicit permission checks on all of these things -- they're just generally set to be accessible by everyone.
Users can also compile their own linkers and execute system binaries however they wish -- it does not matter. The permission is to run code -- any code.
> "read and write apply to the file, not the process"
As I mentioned above, this is explicitly not true. Memory pages on linux are represented as a flat file and they have standard unix permissions allowing the user to read their own memory in their own processes.
This is also true of a process's file descriptors, including ephemeral descriptors such as pipes, sockets, and what have you. It's all accessible using basic filesystem syscalls like open(), seek(), read(), write().
> "In an ideal world, in addition to PKI/signatures, ELF headers would contain explicit permissions like this."
There are indeed ways to do this but-
> "So, for example, htop/top would disallow LD_PRELOAD "
No! Why? There is no reason for this. It's not a security feature and it cannot serve a useful purpose. Anything you might do with LD_ vars and top you could do equally well by just copying and editing top.
> "and the kernel/LSM would police against permission header tampering without root or LSM-specific credentials even by the owner (ideally not root)"
These are features that you would use for a locked down device, but these types of features have no use on a development workstation where users are allowed to write code.
> "This would make a lot of usermode rootkits useless (forcing them to use other means of course). Execute acl only defines the permission to start the program not what others can do to the program during its runtime."
I think you're describing how to lock down an appliance. I'm talking about a development workstation.
> I think you're describing how to lock down an appliance. I'm talking about a development workstation.
No, any production system, even a dev workstation would have IDEs and browsers restricted but their new code or anything else theh need would be permitted.
I suppose the entire non-LSMed Linux/Unix acl system is broken by modern standards. (Windows as well in many similar regards), a process being able to rwx its own memory makes sense. A separate process being able to rwx any process memory so long as the target process is owned by the same user violates principles of mandator access control because it isn't mandatory for arbitrary processes with no explicitly defined relationship to alter each others' memory. In essence if I could summarize this, the permissions model is not granular enough to apply on a per-process runtime basis. You can alter the memory anyways so who cares about preloading and ptrace? That has been the thinking all along but this thinking had not adapted to modern threats and mitigations. I suppose an LSM is the only option and I wouldn't suggest fixing the root cause here due to political impracticality but it would be nice if any desktop and server distro enforced MAC adequately and at least per-process and this shouldn't be considered locked down just normal. Modifying a file, usage of the glibc feature LD_PRELOAD, ptrace,etc... while write and executing while writing and executing a file somewhere in vfs can eventually allow that, these are distinct things,it shouldn't be left for the admin to figure out the implications, the implications should be explicit by design in an ideal world. If there is no explicit permission to specifically allow an operation that constitutes a security risk the OS should prevent that operation. You only described how badly broken things are.
> No! Why? There is no reason for this. It's not a security feature and it cannot serve a useful purpose. Anything you might do with LD_ vars and top you could do equally well by just copying and editing top.
Yes but then the attacker would have to tamper with top (if some other security measure permits it) or use a kernel mode rootkit instead. Security controls address specific risks, in this case LD_PRELOAD is frequently abused by even the most trivial coinmining malware so that specific risk would be addressed as should any other risks in the best way possible. There is no way outside of an LSM for a developer to say "please don't permit preloading,ptrace, memory tampering unless it is this explicitly defined process because bad guys like to abuse these features against me, unless the user is explicitly warned about the dangers and permits the feature"
In reality you can and people do this with selinux and the like wich are fairly cumbersome to manage by an admin (not end user). But allowing devs to declare specific risky features else defaulting to a deny would not be burdensome on devs, admins and it would make the effective security model and interface user friendly.
The same thing can be said with windows process access, debug, thread/dll/code injection,etc.... these security models are outdated and user unfriendly. "If you get pwned, all bets are off" is not a good way to look st security these days.
> "No, any production system, even a dev workstation would have IDEs and browsers restricted but their new code or anything else theh need would be permitted."
This doesn't sound like a net positive policy.
> "I suppose the entire non-LSMed Linux/Unix acl system is broken by modern standards."
Hey look, I've worked in infosec too. These ideas you have come with a cost. You're starting to include language, terminology and design choices that are clearly derived from a large one-size-fits-all corporate environment. I've worked with similar environments and I understand why they exist -- but they are not the norm and are certainly not representative of an ideal computing environment (in terms of security, or in general)
> "You only described how badly broken things are."
I described a development system where things can be changed. You're describing a calcified system where safety is imposed by controls and invariance. Those costs are worth paying for some environments but absolutely not for others.
> "Yes but then the attacker would have to tamper with top (if some other security measure permits it) or use a kernel mode rootkit instead."
No, there are dozens of ways to supply a modified behavior in top. If you're mucking with the environment, why not just change PATH? After all, the LD_ variables are just linker paths. This is a very silly thing to fixate on.
> " There is no way outside of an LSM for a developer to say "please don't permit preloading"
Uh, of course there is. LD_* environment variables are just inputs to the linker. You can trivially change the linker to ignore these variables, or behave differently with them, or whatever.
> "ptrace"
Also really easy to limit with seccomp. This is SOP for containers - it's built into docker. It happens by default for most use cases.
> "But allowing devs to declare specific risky features else defaulting to a deny"
Look, here's the thing: There's always going to be a lowest hanging fruit. I know there's a fairly common compulsion in the security industry to point at the lowhanging fruit and say "that's the problem! remove it!" but this is a fallacy. It's just not true.
What actually matters is whether or not the permission model is cohesive and readily understandable by a developer. Locking down syscalls is and stripping features from a containerized app is a great idea in certain contexts. It's a terrible idea in others.
The ideas you're proposing aren't creating strict controls - they're just chasing misbehaviors. This makes a lot of sense for a large organization playing the numbers game, but it cannot lead to a cohesive, consistent, general purpose security architecture.
Sounds like? Well it is net positive regardless of how it sounds. Intuition is not a good way to direct or measure security.
> Hey look, I've worked in infosec too. These ideas you have come with a cost. You're starting to include language, terminology and design choices that are clearly derived from a large one-size-fits-all corporate environment. I've worked with similar environments and I understand why they exist -- but they are not the norm and are certainly not representative of an ideal computing environment (in terms of security, or in general)
> The ideas you're proposing aren't creating strict controls - they're just chasing misbehaviors. This makes a lot of sense for a large organization playing the numbers game, but it cannot lead to a cohesive, consistent, general purpose security architecture.
So first of all I heavily resent that sentiment! I also had someone else last week refusing to argue from a technical standpoint and esentially say "that's corporate stuff, it's not popular" do you hear yourself? Who cares? Second, it absolutley is not a corporate thing, this is what android,macos,ios are doing, they are very much popular and modern. When an app needs access to a camera you need to give permission right? It wasn't that way at the start and they learned the hard way that allowing a process to access anything because of implied permissions lead to disaster. This is exactly what I am suggesting except I am making it holistic. This is "zero trust" but at the application level. You're stuck in the past and on what linux cliques and popular personas consider popular. I care about bad guys causing harm on any platform, I've seen these risky features getting abused by threst actors that is motivation. From a corporate perspective I don't care about hardening, I care about logs/monitoring because I can afford to log everytime ldpreload or ptrace is used and do something about it. A guy using ubuntu for gaming and web browsing doesn't get like you that installing a program/package without carefully understanding its capability, authorship and the unix permissions model, syscalls, procfs and all kinds of subsystems means he's screwed. For that guy, defaults matter and the default should align with user expectations when it comes to risky features not developer expectations.
> No, there are dozens of ways to supply a modified behavior in top. If you're mucking with the environment, why not just change PATH? After all, the LD_ variables are just linker paths. This is a very silly thing to fixate on
It's not silly because bad guys abuse it. If there are other means default them to deny/off. Stop offloading default security to end users/admins.
> Also really easy to limit with seccomp. This is SOP for containers - it's built into docker. It happens by default for most use cases.
Don't you need to write the app with seccomp support? How can a user turn that off if they want to debug it? And how would an end user know to do this or even a developer, if your default is to allow ptrace what motivates them to limit ptrace?
> Look, here's the thing: There's always going to be a lowest hanging fruit. I know there's a fairly common compulsion in the security industry to point at the lowhanging fruit and say "that's the problem! remove it!" but this is a fallacy. It's just not true.
I don't think what I am saying is getting across. Preloading and ptrace are low hanging frequently abused things for sure and that's why I mentioned them but my suggestion is to overhaul everything not just these things and please making assumptions about my intentions/background. Any device in /dev, any risky file in procfs or sysfs, any abusable syscall , enironment variable, file acl, network connection default them all to a deny and allow users a friendly means by which to disable the restriction. If you don't like my suggestion that's fine so long as the current mess isn't considered acceptable. Security should be the default and risky exposures should be identified and disabled by default by the OS maintainer not the end user or admin.
The corporate way would be how things are now, pay an admin and a consultant and a manager to painstakingly maintain, audit and service file acl restrictions on a fleet of servers and users which isn't ideal for lone admins, newbies and desktop users in general.
> What actually matters is whether or not the permission model is cohesive and readily understandable by a developer. Locking down syscalls is and stripping features from a containerized app is a great idea in certain contexts. It's a terrible idea in others.
No, what actually matters is the security model and default securitu exposures being easily understandable by a minimally experienced user or admin and easily alterable by experienced admins/devs to suit their needs and that isn' how things are today. Your comment about context is spot on, what is bad is your assumption that defaults should be insecure to suit lazy developers instead of default being secure and as needed developers loosening restrictions.
> "they're just chasing misbehaviors"
No, these are real security exposures, of course, if restrictions can be applied at a more fundamental level without impacting users that would also be great. For example with preloading, I get that there are different ways of using that feature so I simply patched it out of glibc in past systems. But it would have been great if there was at least a complile flag to disable it and even better if it was a runtime option disabled by default until I need it. Assumptions are dangerous to everyone.
Lastly, this has to be the longest HN thread I've replied to. You do have solid arguments, I only wish we could have this discourse in a more suitable place.
> "Well it is net positive regardless of how it sounds."
You can't just state that lol. I am certain it is at a minimum unsettled as I've had many discussions with peers across the field about the relative tradeoffs. Including the dangers of superficial measures which aren't in sync with the underlying security architecture.
> " this is what android,macos,ios are doing, they are very much popular and modern"
It's what consumption platforms are doing. It's typically disabled on development platforms because the cost is too high.
> "When an app needs access to a camera you need to give permission right?"
But this isn't what you're describing and this isn't new. Unix has had permissions on devices since its inception.
Using multiple per-app users is becoming more mainstream, but this sort of thing is in sync with what I'm describing above. It has nothing to do with the underlying security model as to how users interact with resources they own, or this wishy-washy concept of intra-user security -- which, again, isn't how these controls are implemented on platforms like Android. Android creates a new user for every application.
Unix has been doing this since the dawn of time, giving individual users or apps permission to specific devices.
What you're talking about is something entirely different: How users interact with their own objects which are already owned by them.
> "Stop offloading default security to end users/admins."
Default security is fine, but you are talking about intra-user controls on objects vs using the system's security architecture (as above: Android uses separate users per app instead)
> "Don't you need to write the app with seccomp support? "
No, you don't! This is something done in a config file when spinning up a container and it will work for arbitrary processes within the container. You can basically configure away certain syscalls and so on if you know they aren't/shouldn't be used.
You can even make this part of an app architecture (aka: android app packaging) to standardize the permissions interface. When apps publish a dockerfile, this is what they're doing.
> "How can a user turn that off if they want to debug it? And how would an end user know to do this or even a developer, if your default is to allow ptrace what motivates them to limit ptrace?"
These features exist for packaged apps and limit access from the app's perspective. Other debug enabled processes (aka: my workstation shell) can still call ptrace and attach. It's all part of the security model.
> "I don't think what I am saying is getting across. Preloading and ptrace are low hanging frequently abused things for sure and that's why I mentioned them but my suggestion is to overhaul everything "
I think we might be talking past each other. It's fine to lock down developed applications to limit scope. This is the entire point of containers!
What I'm talking about though is access from already privileged execution units. We don't need to protect chsh from LD_PRELOAD because if it's running setuid then it's already ignoring it, and if it isn't, there's no threat because we already control all the related objects.
> "what is bad is your assumption that defaults should be insecure "
My suggestions are secure, and in fact are how android, osx, etc currently operate! I have a shell on an android right now. The browser is running as a separate user in a locked down environment. The entirety of /bin/ is not and I'm allowed to play with the linker parameters in development -- but not from within a production app.
I think we agree that locking down a production app is reasonable.
I think where we're getting off the rails is regarding features for a developer who wants to work on their own system -- like LD_PRELOAD. I'm sure you agree that a developer workstation should support this, right? Or an android with developer mode enabled? Etc? Because it does work that way on these modern platforms.
> "Lastly, this has to be the longest HN thread I've replied to. You do have solid arguments, I only wish we could have this discourse in a more suitable place. "
Aren't you re-inventing the SAML / OAuth wheel here? After all, running authentication as a service is precisely what an IDP does.
But interesting option to bundle a micro IDP with the OS. Probably would make a lot of security sense and every app using it would automatically work with a real IDP easily.
I suppose it's sort of described by 'good opportunity for updating the API' - but my #1 reason would be 'you (need to) know systemd config anyway, so lets use it instead of a different thing'.
I'm not the one doing any forcing, I use Arch (btw) which yes does somewhat default to/most people use systemd, and I happen to like it, but you don't have to.
I'm not saying PAM should disappear entirely and nobody should be allowed to use it, I'm saying as someone who happily uses systemd I wouldn't mind/would quite like similar functionality to be part of systemd, and I could stop using PAM.
But if you feel you're forced to use systemd I'm not even saying you should have to use this hypothetical part of it - just like boot, networkd, homed, etc. don't have to be used just because you're using systemd at all.
I don't even hate systemd but like it, will distro maintainers opt to support "systemd pam" alongside old pam or will they discard it? I use systemd more than when I don't but only because it was forced. I can't use devuan and gentoo everywhere. That's why I prefer fixing/updating pam with a backward compatible replacement so maintenance burden is minimized and everyone is happy.
The problem is, lennart and the systemd folks are not happy with systemd being popular, they want to decimate any competition.
I think their point is that if it's in the default configuration of Ubuntu or red hat, it's "shoved down their throat" because it is on by default and they assume they are made to care about it.
No, if it is the only option on every mainstream distro and if I have to keep switching distros because they cave in to the bullshit that I cann "shoved down my throat"
Actually the replacement for PAM is just ... regular software modules. "Implementing in systemd" would simply be making it non-modular. I'll explain:
The P in PAM stands for pluggable - as in, you can change the authentication modules your software is using without recompiling. You can configure sudo to authenticate against ssh_agent, against kerberos, against LDAP, and if systemd had an auth system it could talk to it too. You can also read and write passwords directly from the terminal, if one exists.
To "reimplement in systemd" would simply be to junk the Pluggable and Modularity aspects. You're left with a non-pluggable, single-use client library that talks to systemd. The interface would necessarily be limited, which has both good and bad aspects.
It would also always be possible to write a PAM plugin to talk to the same mechanism, but in a pluggable and modular fashion!
Anyway, this has been done a number of times already, such as with sssd. There of course isn't any need to make it part of systemd directly.
Actually, the Windows LSA architecture - where both verification of initial credentials (PAM) as well as network authentication (GSS) are remoted via IPC to a daemon - has a lot of nice properties. I believe sssd does something similar on Red Hat Linux.
While it is technically the obvious way to go, I just can't wait for the first time the systemd-pamd decides that no, it is working on the correct way, and every linux user that decided to upgrade to the last release-marked version should have ported all of their userland first to deal with the non-communicated change, not being able to log on their machines is their fault.
The openbsd auth system is interesting, I don't know if it is any safer than pam(it probably isn't) however because it operates across process boundaries instead of trying to dlopen everything in the same process it feels more human scale, that is, you feel you can actually debug and modify it without a Phd.
There's a trend that writing is for readers, rather than dictated by company PR. If you are writing for readers, then follow the usual rules for proper nouns where the word is a not-really-initialism which was never meant to be read as its individual letters. PAM™ was always Pam, not P.A.M.
That seems to be a bug with ethical ads. I've already escalated to upstream. Sorry about that! I literally didn't know that was a problem until yesterday. It worked before, something must have changed on their end.