-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
[teleport-update] Set umask 0022 for teleport-update to avoid errors on enable #52725
Conversation
Is this really something that we should be setting? A umask value of 0022 is pretty standard, and if it's not 0022 then having it set to some other value is probably intentional. |
I'm definitely on the fence about this. I went this direction because |
There's also some risk that if (not necessarily now but down the line as the code changes), an attacker may be able to exploit the updater in some way to create executable files. This would probably be why an admin would remove the Personally I'm of the opinion that if most systems default to 0022, then we should build to be compatible with that. If a sysadmin changes the default, then it's up to them (for all applications) to ensure compatibility. |
This is an argument for not fixing the bug. We could just fail on unmask != 0022, with a more clear error. For prior-art though, @espadolini points out that other package management tools do this: |
I can definitely add a loud warning when we change the umask, if the old umask was different. Would that reduce concerns about unexpected behavior? |
That's great, and is probably sufficient to set this, if we and customers are considering the updater a package manager. We had a discussion awhile back as to whether or not the new updater system is a package manager system. It was de facto decided that the updater is not a package manager, otherwise, we should be placing binaries
It would, though not outright eliminate them. If we're considering the updater system to be a package manager system, then I think a warning + set would be fine. If not, IMO we should either warn and either continue or fail, and leave it to the sysadmin to. On a more technical level, if we do want to change the mask, then limiting the scope of the umask change to specific logic (rather than the entire program) is probably the safest way to go. |
Hm, we could fail unless you pass |
Maybe a flag + env (with either one allowing for the umask override)? My concern is that the Completely get that this user interface is a bit worse, but IMO if an admin is changing the umask then they're accepting that things will not always work properly the first time. Of course I am just one datapoint. If you've heard otherwise from customers then we should probably defer to them. |
@fheinecke how does that look? |
I reached out the customer who reported this issue for feedback. Requiring the flag on each invocation would be disruptive UX, so I removed it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm good with dropping the flag so long as we keep the warning message.
Just because it was decided that the updater is theoretically not a package manager doesn't mean it doesn't perform tasks similar to that of a package manager and doesn't mean we can't take inspiration from prior art.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good enough to ship to fix customer breakage. Would appreciate if you reviewed the comments after the PR, and a fix is less urgently needed.
I reached out the customer who reported this issue for feedback. Requiring the flag on each invocation would be disruptive UX, so I removed it.
Sounds great, thanks for asking them! If that's what customers want, then we should do it that way.
tool/teleport-update/main.go
Outdated
@@ -184,6 +184,13 @@ func Run(args []string) int { | |||
return 1 | |||
} | |||
|
|||
// Set required umask for most commands, and warn loudly if it changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be set for all commands or just ones that install or update? I'm not familiar enough with the tool to know where this is and is not needed.
Alternatively, can this more tightly wrap the actual filesystem write calls? This would reduce the likelihood of a vulnerability in the future where an attacker is able to use the updater to write executable files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be set for all commands or just ones that install or update?
It needs to be set for all commands that must run as root and write system files, so I scoped it to just those commands.
I updated the godoc to clarify this as well. We can make sure that it doesn't get set for user commands.
(This is similar to systemd, in a way. Systemd system services always get Umask = 0022
unless they explicitly define their own umask. There is no way for root to change that behavior. However, user services respect the user umask.)
Alternatively, can this more tightly wrap the actual filesystem write calls?
This is tricky, because the umask is process-global, and changing it impacts all goroutines in a thread-unsafe manner. I agree with your point about syscall.Umask
having important security implications, and I want to avoid calling it in importable code that could impact other goroutines by silently modifying their file permissions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might not be feasible, but could all functions that could be feasibly impacted by this pass around a mutex, where if a given function held the lock, it could set/unset the umask? Or maybe there could be two "groups" of functions - one privileged and one not - that would share this mutex.
If the local shell has an unusual umask, teleport-update will refuse to complete
teleport-update enable
:This PR changes the umask of the whole
teleport-update
process to ensure all operations are consistent with teleport-update when run by systemd (which always uses 0022). This would be undesirable for most CLIs, butteleport-update
should never create files as a normal user, or create files in normal user directories.As a workaround until this PR is merged, users can run
umask 0022
beforeteleport-update enable
.--
changelog: Allow teleport-update to be used in shells that set a restrictive umask
--
The
teleport-update
binary will be used to enable, disable, and trigger automatic Teleport agent updates. The new auto-updates system manages a local installation of the cluster-specified version of Teleport stored in/opt/teleport
.RFD: #47126
Goal (internal): https://github.com/gravitational/cloud/issues/11856