What is required by a process to set its uid to 0 (root)? The 2019 Stack Overflow Developer...
What to do when moving next to a bird sanctuary with a loosely-domesticated cat?
Keeping a retro style to sci-fi spaceships?
How do I free up internal storage if I don't have any apps downloaded?
How come people say “Would of”?
Can you cast a spell on someone in the Ethereal Plane, if you are on the Material Plane and have the True Seeing spell active?
Short story: man watches girlfriend's spaceship entering a 'black hole' (?) forever
Worn-tile Scrabble
Can there be female White Walkers?
Is it ethical to upload a automatically generated paper to a non peer-reviewed site as part of a larger research?
What is this sharp, curved notch on my knife for?
"as much details as you can remember"
What can I do if neighbor is blocking my solar panels intentionally
What information about me do stores get via my credit card?
Likelihood that a superbug or lethal virus could come from a landfill
Accepted by European university, rejected by all American ones I applied to? Possible reasons?
Pokemon Turn Based battle (Python)
Why doesn't shell automatically fix "useless use of cat"?
Deal with toxic manager when you can't quit
Why did Peik say, "I'm not an animal"?
Is it ok to offer lower paid work as a trial period before negotiating for a full-time job?
How to support a colleague who finds meetings extremely tiring?
Is there a way to generate a uniformly distributed point on a sphere from a fixed amount of random real numbers?
If I score a critical hit on an 18 or higher, what are my chances of getting a critical hit if I roll 3d20?
Will it cause any balance problems to have PCs level up and gain the benefits of a long rest mid-fight?
What is required by a process to set its uid to 0 (root)?
The 2019 Stack Overflow Developer Survey Results Are InAllow setuid on shell scriptskernel: Namespaces supportseteuid fails even when all UIDs are 0using Set uid to run a root command from non-root user`kill -s TERM` works, `kill -s ABRT` gets “Operation not permitted”What would be the best way to work around this glibc problem?Group memberships and setuid/setgid processesWhy mac os x does not set uid bit for /usr/bin/passwdWhat exactly differentiates the root user from every other user?Set-uid executable and resulting process userDo I need to set uid bit in this case?How to drop privilege of root user initiated process?Linux - why do the su and sudo binaries need to be set-UID root?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
I am completely new to *NIX based OSes. One of the things that baffles me is that a process or program may execute setuid(0)
and then perform privileged operations and revert back to its normal uid.
My question is what is the mechanism in *NIX to prevent any arbitrary process from possessing root ?
If I write a simple C program that calls setuid(0)
under what conditions will that call succeed and under what conditions will it fail ?
permissions setuid
add a comment |
I am completely new to *NIX based OSes. One of the things that baffles me is that a process or program may execute setuid(0)
and then perform privileged operations and revert back to its normal uid.
My question is what is the mechanism in *NIX to prevent any arbitrary process from possessing root ?
If I write a simple C program that calls setuid(0)
under what conditions will that call succeed and under what conditions will it fail ?
permissions setuid
Yes so which user can? Can only a root user invoke this method?
– ng.newbie
Oct 22 '17 at 16:36
If we accept your unproven claim that any process can run as root, that would be a major security hole that has for some reason gone unpatched in the decades unix has been available. A simpler answer is instead that your claim is false; why then would you make such a claim?
– thrig
Oct 22 '17 at 16:59
@thrig What confuses me is that looking at the source for the su binary - you can see that there is a call tosetuid(0)
, so was just wondering how it is possible there. And if it possible there why isn't it possible in other cases ? What prerequisites are needed for the method to successfully execute ? That was my question. I know my claim is false.
– ng.newbie
Oct 22 '17 at 17:03
su
has the setuid permission bit set
– thrig
Oct 22 '17 at 18:10
@thrig Would you please tell me which permission but needs to be set in order for a successful call to setuid(0) ?
– ng.newbie
Oct 22 '17 at 18:29
add a comment |
I am completely new to *NIX based OSes. One of the things that baffles me is that a process or program may execute setuid(0)
and then perform privileged operations and revert back to its normal uid.
My question is what is the mechanism in *NIX to prevent any arbitrary process from possessing root ?
If I write a simple C program that calls setuid(0)
under what conditions will that call succeed and under what conditions will it fail ?
permissions setuid
I am completely new to *NIX based OSes. One of the things that baffles me is that a process or program may execute setuid(0)
and then perform privileged operations and revert back to its normal uid.
My question is what is the mechanism in *NIX to prevent any arbitrary process from possessing root ?
If I write a simple C program that calls setuid(0)
under what conditions will that call succeed and under what conditions will it fail ?
permissions setuid
permissions setuid
asked Oct 22 '17 at 16:24
ng.newbieng.newbie
268412
268412
Yes so which user can? Can only a root user invoke this method?
– ng.newbie
Oct 22 '17 at 16:36
If we accept your unproven claim that any process can run as root, that would be a major security hole that has for some reason gone unpatched in the decades unix has been available. A simpler answer is instead that your claim is false; why then would you make such a claim?
– thrig
Oct 22 '17 at 16:59
@thrig What confuses me is that looking at the source for the su binary - you can see that there is a call tosetuid(0)
, so was just wondering how it is possible there. And if it possible there why isn't it possible in other cases ? What prerequisites are needed for the method to successfully execute ? That was my question. I know my claim is false.
– ng.newbie
Oct 22 '17 at 17:03
su
has the setuid permission bit set
– thrig
Oct 22 '17 at 18:10
@thrig Would you please tell me which permission but needs to be set in order for a successful call to setuid(0) ?
– ng.newbie
Oct 22 '17 at 18:29
add a comment |
Yes so which user can? Can only a root user invoke this method?
– ng.newbie
Oct 22 '17 at 16:36
If we accept your unproven claim that any process can run as root, that would be a major security hole that has for some reason gone unpatched in the decades unix has been available. A simpler answer is instead that your claim is false; why then would you make such a claim?
– thrig
Oct 22 '17 at 16:59
@thrig What confuses me is that looking at the source for the su binary - you can see that there is a call tosetuid(0)
, so was just wondering how it is possible there. And if it possible there why isn't it possible in other cases ? What prerequisites are needed for the method to successfully execute ? That was my question. I know my claim is false.
– ng.newbie
Oct 22 '17 at 17:03
su
has the setuid permission bit set
– thrig
Oct 22 '17 at 18:10
@thrig Would you please tell me which permission but needs to be set in order for a successful call to setuid(0) ?
– ng.newbie
Oct 22 '17 at 18:29
Yes so which user can? Can only a root user invoke this method?
– ng.newbie
Oct 22 '17 at 16:36
Yes so which user can? Can only a root user invoke this method?
– ng.newbie
Oct 22 '17 at 16:36
If we accept your unproven claim that any process can run as root, that would be a major security hole that has for some reason gone unpatched in the decades unix has been available. A simpler answer is instead that your claim is false; why then would you make such a claim?
– thrig
Oct 22 '17 at 16:59
If we accept your unproven claim that any process can run as root, that would be a major security hole that has for some reason gone unpatched in the decades unix has been available. A simpler answer is instead that your claim is false; why then would you make such a claim?
– thrig
Oct 22 '17 at 16:59
@thrig What confuses me is that looking at the source for the su binary - you can see that there is a call to
setuid(0)
, so was just wondering how it is possible there. And if it possible there why isn't it possible in other cases ? What prerequisites are needed for the method to successfully execute ? That was my question. I know my claim is false.– ng.newbie
Oct 22 '17 at 17:03
@thrig What confuses me is that looking at the source for the su binary - you can see that there is a call to
setuid(0)
, so was just wondering how it is possible there. And if it possible there why isn't it possible in other cases ? What prerequisites are needed for the method to successfully execute ? That was my question. I know my claim is false.– ng.newbie
Oct 22 '17 at 17:03
su
has the setuid permission bit set– thrig
Oct 22 '17 at 18:10
su
has the setuid permission bit set– thrig
Oct 22 '17 at 18:10
@thrig Would you please tell me which permission but needs to be set in order for a successful call to setuid(0) ?
– ng.newbie
Oct 22 '17 at 18:29
@thrig Would you please tell me which permission but needs to be set in order for a successful call to setuid(0) ?
– ng.newbie
Oct 22 '17 at 18:29
add a comment |
3 Answers
3
active
oldest
votes
The basic idea is that a process may only reduce its privileges. A process may not gain any privileges. There is one exception: a process that executes a program from a file that has a setuid or setgid flag set gains the privileges expressed by this flag.
Note how this mechanism does not allow a program to run arbitrary code with elevated privileges. The only code that can be run with elevated privileges is setuid/setgid executables.
The root user, i.e. the user with id 0, is more privileged than anything else. A process with user 0 is allowed to do anything. (Group 0 is not special.)
Most processes keep running with the same privileges. Programs that log a user in or start a daemon start as root, then drop all privileges and execute the desired program as the user (e.g. the user's login shell or session manager, or the daemon). Setuid (or setgid) programs can operate as the target user and group, but many switch between the caller's privileges and their own additional privileges depending on what they're doing, using the mechanisms I am going to describe now.
Every process has three user IDs: the real user ID (RUID), the effective user ID (EUID), and the saved user ID (SUID). The idea is that a process can temporarily gain privileges, then abandon them when it doesn't need them anymore, and gain them back when it needs them again. There's a similar mechanism for groups, with a real group ID (RGID), an effective group ID (EGID), a saved group ID (SGID) and supplementary groups. The way they work is:
- Most programs keep the same real UID and GID throughout. The main exception is login programs (and daemon launchers), which switch their RUID and RGID from root to the target user and group.
- File access, and operations that require root privileges, look at the effective UID and GID. Privileged programs often switch their effective IDs depending on whether they're executing a privileged operation.
- The saved IDs allow switching the effective IDs back and forth. A program may switch its effective ID between the saved ID and the real ID.
A program that needs to perform certain actions with root privileges normally runs with its EUID set to the RUID, but calls seteuid
to set its EUID to 0 before running the action that requires privileges and calls seteuid
again to the EUID change back to the RUID afterwards. In order to perform the call to seteuid(0)
even though the EUID at the time is not 0, the SUID must be 0.
The same mechanism can be used to gain group privileges. A typical example is a game that saves high scores of local users. The game executable is setgid games
. When the game starts, its EGID is set to games
, but it changes back to the RGID so as not to risk performing any action that the user isn't normally allowed to do. When the game is about to save a high score, it changes its EGID temporarily to games
. This way:
- Because the high score file requires privileges that ordinary users don't have, the only way to add an entry to the high score file is to play the game.
- If there's a security vulnerability in the game, the worst that it can do is grant a user permission to the
games
group, allowing them to cheat on high scores. - If there's a bug in the game that doesn't result in the program calling the
setegid
function, e.g. a bug that only causes the game to write to an unintended file, then that bug doesn't allow cheating on high scores, because the game doesn't have the permission to write to the high score file without callingsetegid
.
What I wrote above is describes a basic traditional Unix system. Some modern systems have other features that complement the traditional Unix privilege model. These features come in addition to the basic user/group effective/real system and sometimes interact with it. I won't go into any detail about these additional features, but I'll just mention three features of the Linux security model.
- The permission to perform many actions is granted via a capability rather than to user ID 0. For example, changing user IDs requires the capability
CAP_SETUID
, rather than having user ID 0. Programs running as user ID 0 receive all capabilities unless they go out of their way, and programs running withCAP_SETUID
can acquire root privileges, so in practice running as root and havingCAP_SETUID
are equivalent. - Linux has several security frameworks that can restrict what a process can do, even if that process is running as user ID 0. With some security frameworks, unlike with the traditional Unix model and capabilities, a process may gain privileges upon
execve
due to the security framework's configuration rather than due to flags in the executable file's metadata. - Linux has user namespaces. A process running as root in a namespace only has privileges inside that namespace.
Thanks for the explanation. I had no idea about the saved ID stuff!
– jjohn
Jan 15 '18 at 17:22
add a comment |
In addition to the user id, a process is also associated with an effective user id. When a setuid root program like su
is executed, the effective uid is set to 0, but the real uid stays the same. The effective uid is, as the name says, the uid that is used for permission checks, the real uid just tells "who we really are". A process with an effective uid equal to zero can successfully call setuid(0)
to change the real uid to zero.
So all processes that need to execute setuid(0) the effective uid needs to be 0 in advance, correct ? Then why isn't the effective uid just used for root operations ? Why callsetuid(0)
again ? I mean any process with effective uid set to 0 will obviously be able to execute setuid(0), so why have a call again the code ?
– ng.newbie
Oct 22 '17 at 18:26
Also is there any way a normal process can set it's eid to 0 so it can successfully callsetuid(0)
?
– ng.newbie
Oct 22 '17 at 18:28
Quoting thesetuid(2)
man page: "setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set." So calling setuid(0) as (effective) root just sets the real uid to 0, too. Not doing this affects for example theaccess(2)
system call, which uses the real uid to do the check.ps
also shows thesu
process as running by root because is shows the real uid. (Btw. theaccess(2)
system call is essentially useless because of race conditions.)
– Johan Myréen
Oct 22 '17 at 18:51
No, there is no way a normal (unprivileged) process can successfully callsetuid(0)
. An unprivileged program can usesetuid()
to change its effective uid, though. If the program is started as suid non-root, the effective uid and the real uid are different. The program can callsetuid()
to set the effective uid to the real uid. A privileged program can usesetuid()
to drop privileges by setting both uids to a value of its own choice.
– Johan Myréen
Oct 22 '17 at 19:30
Why is there an effective uid and a real uid ? What does that accomplish? What would be the harm if there was only one uid?
– ng.newbie
Oct 22 '17 at 19:57
|
show 1 more comment
In order for setuid(some_uid) to work, the following conditions need to be met:
- The executable's file needs to be owned by some_uid1.
- The executable's file needs to have the setuid permission.
The setuid permission can be granted or removed with chmod
:
chmod u+s execuables_file_name
chmod u-s execuables_file_name
The setuid permission can be seen when displaying the file permissions as the execute permission will be replaced by an s
if the setuid permission is granted.
> ll execuables_file_name
-rwsrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
If for some reason the owner user doesn't have execute permissions, then it will be displayed as a capital S instead:
> ll execuables_file_name
-rwSrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
Note that scripts are an entirely different beast.
A thorough guide to permissions.
1. setuid(some_uid) will also succeed if transitioning to the user id that started the process
New contributor
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f399746%2fwhat-is-required-by-a-process-to-set-its-uid-to-0-root%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The basic idea is that a process may only reduce its privileges. A process may not gain any privileges. There is one exception: a process that executes a program from a file that has a setuid or setgid flag set gains the privileges expressed by this flag.
Note how this mechanism does not allow a program to run arbitrary code with elevated privileges. The only code that can be run with elevated privileges is setuid/setgid executables.
The root user, i.e. the user with id 0, is more privileged than anything else. A process with user 0 is allowed to do anything. (Group 0 is not special.)
Most processes keep running with the same privileges. Programs that log a user in or start a daemon start as root, then drop all privileges and execute the desired program as the user (e.g. the user's login shell or session manager, or the daemon). Setuid (or setgid) programs can operate as the target user and group, but many switch between the caller's privileges and their own additional privileges depending on what they're doing, using the mechanisms I am going to describe now.
Every process has three user IDs: the real user ID (RUID), the effective user ID (EUID), and the saved user ID (SUID). The idea is that a process can temporarily gain privileges, then abandon them when it doesn't need them anymore, and gain them back when it needs them again. There's a similar mechanism for groups, with a real group ID (RGID), an effective group ID (EGID), a saved group ID (SGID) and supplementary groups. The way they work is:
- Most programs keep the same real UID and GID throughout. The main exception is login programs (and daemon launchers), which switch their RUID and RGID from root to the target user and group.
- File access, and operations that require root privileges, look at the effective UID and GID. Privileged programs often switch their effective IDs depending on whether they're executing a privileged operation.
- The saved IDs allow switching the effective IDs back and forth. A program may switch its effective ID between the saved ID and the real ID.
A program that needs to perform certain actions with root privileges normally runs with its EUID set to the RUID, but calls seteuid
to set its EUID to 0 before running the action that requires privileges and calls seteuid
again to the EUID change back to the RUID afterwards. In order to perform the call to seteuid(0)
even though the EUID at the time is not 0, the SUID must be 0.
The same mechanism can be used to gain group privileges. A typical example is a game that saves high scores of local users. The game executable is setgid games
. When the game starts, its EGID is set to games
, but it changes back to the RGID so as not to risk performing any action that the user isn't normally allowed to do. When the game is about to save a high score, it changes its EGID temporarily to games
. This way:
- Because the high score file requires privileges that ordinary users don't have, the only way to add an entry to the high score file is to play the game.
- If there's a security vulnerability in the game, the worst that it can do is grant a user permission to the
games
group, allowing them to cheat on high scores. - If there's a bug in the game that doesn't result in the program calling the
setegid
function, e.g. a bug that only causes the game to write to an unintended file, then that bug doesn't allow cheating on high scores, because the game doesn't have the permission to write to the high score file without callingsetegid
.
What I wrote above is describes a basic traditional Unix system. Some modern systems have other features that complement the traditional Unix privilege model. These features come in addition to the basic user/group effective/real system and sometimes interact with it. I won't go into any detail about these additional features, but I'll just mention three features of the Linux security model.
- The permission to perform many actions is granted via a capability rather than to user ID 0. For example, changing user IDs requires the capability
CAP_SETUID
, rather than having user ID 0. Programs running as user ID 0 receive all capabilities unless they go out of their way, and programs running withCAP_SETUID
can acquire root privileges, so in practice running as root and havingCAP_SETUID
are equivalent. - Linux has several security frameworks that can restrict what a process can do, even if that process is running as user ID 0. With some security frameworks, unlike with the traditional Unix model and capabilities, a process may gain privileges upon
execve
due to the security framework's configuration rather than due to flags in the executable file's metadata. - Linux has user namespaces. A process running as root in a namespace only has privileges inside that namespace.
Thanks for the explanation. I had no idea about the saved ID stuff!
– jjohn
Jan 15 '18 at 17:22
add a comment |
The basic idea is that a process may only reduce its privileges. A process may not gain any privileges. There is one exception: a process that executes a program from a file that has a setuid or setgid flag set gains the privileges expressed by this flag.
Note how this mechanism does not allow a program to run arbitrary code with elevated privileges. The only code that can be run with elevated privileges is setuid/setgid executables.
The root user, i.e. the user with id 0, is more privileged than anything else. A process with user 0 is allowed to do anything. (Group 0 is not special.)
Most processes keep running with the same privileges. Programs that log a user in or start a daemon start as root, then drop all privileges and execute the desired program as the user (e.g. the user's login shell or session manager, or the daemon). Setuid (or setgid) programs can operate as the target user and group, but many switch between the caller's privileges and their own additional privileges depending on what they're doing, using the mechanisms I am going to describe now.
Every process has three user IDs: the real user ID (RUID), the effective user ID (EUID), and the saved user ID (SUID). The idea is that a process can temporarily gain privileges, then abandon them when it doesn't need them anymore, and gain them back when it needs them again. There's a similar mechanism for groups, with a real group ID (RGID), an effective group ID (EGID), a saved group ID (SGID) and supplementary groups. The way they work is:
- Most programs keep the same real UID and GID throughout. The main exception is login programs (and daemon launchers), which switch their RUID and RGID from root to the target user and group.
- File access, and operations that require root privileges, look at the effective UID and GID. Privileged programs often switch their effective IDs depending on whether they're executing a privileged operation.
- The saved IDs allow switching the effective IDs back and forth. A program may switch its effective ID between the saved ID and the real ID.
A program that needs to perform certain actions with root privileges normally runs with its EUID set to the RUID, but calls seteuid
to set its EUID to 0 before running the action that requires privileges and calls seteuid
again to the EUID change back to the RUID afterwards. In order to perform the call to seteuid(0)
even though the EUID at the time is not 0, the SUID must be 0.
The same mechanism can be used to gain group privileges. A typical example is a game that saves high scores of local users. The game executable is setgid games
. When the game starts, its EGID is set to games
, but it changes back to the RGID so as not to risk performing any action that the user isn't normally allowed to do. When the game is about to save a high score, it changes its EGID temporarily to games
. This way:
- Because the high score file requires privileges that ordinary users don't have, the only way to add an entry to the high score file is to play the game.
- If there's a security vulnerability in the game, the worst that it can do is grant a user permission to the
games
group, allowing them to cheat on high scores. - If there's a bug in the game that doesn't result in the program calling the
setegid
function, e.g. a bug that only causes the game to write to an unintended file, then that bug doesn't allow cheating on high scores, because the game doesn't have the permission to write to the high score file without callingsetegid
.
What I wrote above is describes a basic traditional Unix system. Some modern systems have other features that complement the traditional Unix privilege model. These features come in addition to the basic user/group effective/real system and sometimes interact with it. I won't go into any detail about these additional features, but I'll just mention three features of the Linux security model.
- The permission to perform many actions is granted via a capability rather than to user ID 0. For example, changing user IDs requires the capability
CAP_SETUID
, rather than having user ID 0. Programs running as user ID 0 receive all capabilities unless they go out of their way, and programs running withCAP_SETUID
can acquire root privileges, so in practice running as root and havingCAP_SETUID
are equivalent. - Linux has several security frameworks that can restrict what a process can do, even if that process is running as user ID 0. With some security frameworks, unlike with the traditional Unix model and capabilities, a process may gain privileges upon
execve
due to the security framework's configuration rather than due to flags in the executable file's metadata. - Linux has user namespaces. A process running as root in a namespace only has privileges inside that namespace.
Thanks for the explanation. I had no idea about the saved ID stuff!
– jjohn
Jan 15 '18 at 17:22
add a comment |
The basic idea is that a process may only reduce its privileges. A process may not gain any privileges. There is one exception: a process that executes a program from a file that has a setuid or setgid flag set gains the privileges expressed by this flag.
Note how this mechanism does not allow a program to run arbitrary code with elevated privileges. The only code that can be run with elevated privileges is setuid/setgid executables.
The root user, i.e. the user with id 0, is more privileged than anything else. A process with user 0 is allowed to do anything. (Group 0 is not special.)
Most processes keep running with the same privileges. Programs that log a user in or start a daemon start as root, then drop all privileges and execute the desired program as the user (e.g. the user's login shell or session manager, or the daemon). Setuid (or setgid) programs can operate as the target user and group, but many switch between the caller's privileges and their own additional privileges depending on what they're doing, using the mechanisms I am going to describe now.
Every process has three user IDs: the real user ID (RUID), the effective user ID (EUID), and the saved user ID (SUID). The idea is that a process can temporarily gain privileges, then abandon them when it doesn't need them anymore, and gain them back when it needs them again. There's a similar mechanism for groups, with a real group ID (RGID), an effective group ID (EGID), a saved group ID (SGID) and supplementary groups. The way they work is:
- Most programs keep the same real UID and GID throughout. The main exception is login programs (and daemon launchers), which switch their RUID and RGID from root to the target user and group.
- File access, and operations that require root privileges, look at the effective UID and GID. Privileged programs often switch their effective IDs depending on whether they're executing a privileged operation.
- The saved IDs allow switching the effective IDs back and forth. A program may switch its effective ID between the saved ID and the real ID.
A program that needs to perform certain actions with root privileges normally runs with its EUID set to the RUID, but calls seteuid
to set its EUID to 0 before running the action that requires privileges and calls seteuid
again to the EUID change back to the RUID afterwards. In order to perform the call to seteuid(0)
even though the EUID at the time is not 0, the SUID must be 0.
The same mechanism can be used to gain group privileges. A typical example is a game that saves high scores of local users. The game executable is setgid games
. When the game starts, its EGID is set to games
, but it changes back to the RGID so as not to risk performing any action that the user isn't normally allowed to do. When the game is about to save a high score, it changes its EGID temporarily to games
. This way:
- Because the high score file requires privileges that ordinary users don't have, the only way to add an entry to the high score file is to play the game.
- If there's a security vulnerability in the game, the worst that it can do is grant a user permission to the
games
group, allowing them to cheat on high scores. - If there's a bug in the game that doesn't result in the program calling the
setegid
function, e.g. a bug that only causes the game to write to an unintended file, then that bug doesn't allow cheating on high scores, because the game doesn't have the permission to write to the high score file without callingsetegid
.
What I wrote above is describes a basic traditional Unix system. Some modern systems have other features that complement the traditional Unix privilege model. These features come in addition to the basic user/group effective/real system and sometimes interact with it. I won't go into any detail about these additional features, but I'll just mention three features of the Linux security model.
- The permission to perform many actions is granted via a capability rather than to user ID 0. For example, changing user IDs requires the capability
CAP_SETUID
, rather than having user ID 0. Programs running as user ID 0 receive all capabilities unless they go out of their way, and programs running withCAP_SETUID
can acquire root privileges, so in practice running as root and havingCAP_SETUID
are equivalent. - Linux has several security frameworks that can restrict what a process can do, even if that process is running as user ID 0. With some security frameworks, unlike with the traditional Unix model and capabilities, a process may gain privileges upon
execve
due to the security framework's configuration rather than due to flags in the executable file's metadata. - Linux has user namespaces. A process running as root in a namespace only has privileges inside that namespace.
The basic idea is that a process may only reduce its privileges. A process may not gain any privileges. There is one exception: a process that executes a program from a file that has a setuid or setgid flag set gains the privileges expressed by this flag.
Note how this mechanism does not allow a program to run arbitrary code with elevated privileges. The only code that can be run with elevated privileges is setuid/setgid executables.
The root user, i.e. the user with id 0, is more privileged than anything else. A process with user 0 is allowed to do anything. (Group 0 is not special.)
Most processes keep running with the same privileges. Programs that log a user in or start a daemon start as root, then drop all privileges and execute the desired program as the user (e.g. the user's login shell or session manager, or the daemon). Setuid (or setgid) programs can operate as the target user and group, but many switch between the caller's privileges and their own additional privileges depending on what they're doing, using the mechanisms I am going to describe now.
Every process has three user IDs: the real user ID (RUID), the effective user ID (EUID), and the saved user ID (SUID). The idea is that a process can temporarily gain privileges, then abandon them when it doesn't need them anymore, and gain them back when it needs them again. There's a similar mechanism for groups, with a real group ID (RGID), an effective group ID (EGID), a saved group ID (SGID) and supplementary groups. The way they work is:
- Most programs keep the same real UID and GID throughout. The main exception is login programs (and daemon launchers), which switch their RUID and RGID from root to the target user and group.
- File access, and operations that require root privileges, look at the effective UID and GID. Privileged programs often switch their effective IDs depending on whether they're executing a privileged operation.
- The saved IDs allow switching the effective IDs back and forth. A program may switch its effective ID between the saved ID and the real ID.
A program that needs to perform certain actions with root privileges normally runs with its EUID set to the RUID, but calls seteuid
to set its EUID to 0 before running the action that requires privileges and calls seteuid
again to the EUID change back to the RUID afterwards. In order to perform the call to seteuid(0)
even though the EUID at the time is not 0, the SUID must be 0.
The same mechanism can be used to gain group privileges. A typical example is a game that saves high scores of local users. The game executable is setgid games
. When the game starts, its EGID is set to games
, but it changes back to the RGID so as not to risk performing any action that the user isn't normally allowed to do. When the game is about to save a high score, it changes its EGID temporarily to games
. This way:
- Because the high score file requires privileges that ordinary users don't have, the only way to add an entry to the high score file is to play the game.
- If there's a security vulnerability in the game, the worst that it can do is grant a user permission to the
games
group, allowing them to cheat on high scores. - If there's a bug in the game that doesn't result in the program calling the
setegid
function, e.g. a bug that only causes the game to write to an unintended file, then that bug doesn't allow cheating on high scores, because the game doesn't have the permission to write to the high score file without callingsetegid
.
What I wrote above is describes a basic traditional Unix system. Some modern systems have other features that complement the traditional Unix privilege model. These features come in addition to the basic user/group effective/real system and sometimes interact with it. I won't go into any detail about these additional features, but I'll just mention three features of the Linux security model.
- The permission to perform many actions is granted via a capability rather than to user ID 0. For example, changing user IDs requires the capability
CAP_SETUID
, rather than having user ID 0. Programs running as user ID 0 receive all capabilities unless they go out of their way, and programs running withCAP_SETUID
can acquire root privileges, so in practice running as root and havingCAP_SETUID
are equivalent. - Linux has several security frameworks that can restrict what a process can do, even if that process is running as user ID 0. With some security frameworks, unlike with the traditional Unix model and capabilities, a process may gain privileges upon
execve
due to the security framework's configuration rather than due to flags in the executable file's metadata. - Linux has user namespaces. A process running as root in a namespace only has privileges inside that namespace.
edited Jan 22 at 7:42
Torin
46729
46729
answered Oct 23 '17 at 0:10
GillesGilles
547k13011131629
547k13011131629
Thanks for the explanation. I had no idea about the saved ID stuff!
– jjohn
Jan 15 '18 at 17:22
add a comment |
Thanks for the explanation. I had no idea about the saved ID stuff!
– jjohn
Jan 15 '18 at 17:22
Thanks for the explanation. I had no idea about the saved ID stuff!
– jjohn
Jan 15 '18 at 17:22
Thanks for the explanation. I had no idea about the saved ID stuff!
– jjohn
Jan 15 '18 at 17:22
add a comment |
In addition to the user id, a process is also associated with an effective user id. When a setuid root program like su
is executed, the effective uid is set to 0, but the real uid stays the same. The effective uid is, as the name says, the uid that is used for permission checks, the real uid just tells "who we really are". A process with an effective uid equal to zero can successfully call setuid(0)
to change the real uid to zero.
So all processes that need to execute setuid(0) the effective uid needs to be 0 in advance, correct ? Then why isn't the effective uid just used for root operations ? Why callsetuid(0)
again ? I mean any process with effective uid set to 0 will obviously be able to execute setuid(0), so why have a call again the code ?
– ng.newbie
Oct 22 '17 at 18:26
Also is there any way a normal process can set it's eid to 0 so it can successfully callsetuid(0)
?
– ng.newbie
Oct 22 '17 at 18:28
Quoting thesetuid(2)
man page: "setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set." So calling setuid(0) as (effective) root just sets the real uid to 0, too. Not doing this affects for example theaccess(2)
system call, which uses the real uid to do the check.ps
also shows thesu
process as running by root because is shows the real uid. (Btw. theaccess(2)
system call is essentially useless because of race conditions.)
– Johan Myréen
Oct 22 '17 at 18:51
No, there is no way a normal (unprivileged) process can successfully callsetuid(0)
. An unprivileged program can usesetuid()
to change its effective uid, though. If the program is started as suid non-root, the effective uid and the real uid are different. The program can callsetuid()
to set the effective uid to the real uid. A privileged program can usesetuid()
to drop privileges by setting both uids to a value of its own choice.
– Johan Myréen
Oct 22 '17 at 19:30
Why is there an effective uid and a real uid ? What does that accomplish? What would be the harm if there was only one uid?
– ng.newbie
Oct 22 '17 at 19:57
|
show 1 more comment
In addition to the user id, a process is also associated with an effective user id. When a setuid root program like su
is executed, the effective uid is set to 0, but the real uid stays the same. The effective uid is, as the name says, the uid that is used for permission checks, the real uid just tells "who we really are". A process with an effective uid equal to zero can successfully call setuid(0)
to change the real uid to zero.
So all processes that need to execute setuid(0) the effective uid needs to be 0 in advance, correct ? Then why isn't the effective uid just used for root operations ? Why callsetuid(0)
again ? I mean any process with effective uid set to 0 will obviously be able to execute setuid(0), so why have a call again the code ?
– ng.newbie
Oct 22 '17 at 18:26
Also is there any way a normal process can set it's eid to 0 so it can successfully callsetuid(0)
?
– ng.newbie
Oct 22 '17 at 18:28
Quoting thesetuid(2)
man page: "setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set." So calling setuid(0) as (effective) root just sets the real uid to 0, too. Not doing this affects for example theaccess(2)
system call, which uses the real uid to do the check.ps
also shows thesu
process as running by root because is shows the real uid. (Btw. theaccess(2)
system call is essentially useless because of race conditions.)
– Johan Myréen
Oct 22 '17 at 18:51
No, there is no way a normal (unprivileged) process can successfully callsetuid(0)
. An unprivileged program can usesetuid()
to change its effective uid, though. If the program is started as suid non-root, the effective uid and the real uid are different. The program can callsetuid()
to set the effective uid to the real uid. A privileged program can usesetuid()
to drop privileges by setting both uids to a value of its own choice.
– Johan Myréen
Oct 22 '17 at 19:30
Why is there an effective uid and a real uid ? What does that accomplish? What would be the harm if there was only one uid?
– ng.newbie
Oct 22 '17 at 19:57
|
show 1 more comment
In addition to the user id, a process is also associated with an effective user id. When a setuid root program like su
is executed, the effective uid is set to 0, but the real uid stays the same. The effective uid is, as the name says, the uid that is used for permission checks, the real uid just tells "who we really are". A process with an effective uid equal to zero can successfully call setuid(0)
to change the real uid to zero.
In addition to the user id, a process is also associated with an effective user id. When a setuid root program like su
is executed, the effective uid is set to 0, but the real uid stays the same. The effective uid is, as the name says, the uid that is used for permission checks, the real uid just tells "who we really are". A process with an effective uid equal to zero can successfully call setuid(0)
to change the real uid to zero.
answered Oct 22 '17 at 18:20
Johan MyréenJohan Myréen
7,91711625
7,91711625
So all processes that need to execute setuid(0) the effective uid needs to be 0 in advance, correct ? Then why isn't the effective uid just used for root operations ? Why callsetuid(0)
again ? I mean any process with effective uid set to 0 will obviously be able to execute setuid(0), so why have a call again the code ?
– ng.newbie
Oct 22 '17 at 18:26
Also is there any way a normal process can set it's eid to 0 so it can successfully callsetuid(0)
?
– ng.newbie
Oct 22 '17 at 18:28
Quoting thesetuid(2)
man page: "setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set." So calling setuid(0) as (effective) root just sets the real uid to 0, too. Not doing this affects for example theaccess(2)
system call, which uses the real uid to do the check.ps
also shows thesu
process as running by root because is shows the real uid. (Btw. theaccess(2)
system call is essentially useless because of race conditions.)
– Johan Myréen
Oct 22 '17 at 18:51
No, there is no way a normal (unprivileged) process can successfully callsetuid(0)
. An unprivileged program can usesetuid()
to change its effective uid, though. If the program is started as suid non-root, the effective uid and the real uid are different. The program can callsetuid()
to set the effective uid to the real uid. A privileged program can usesetuid()
to drop privileges by setting both uids to a value of its own choice.
– Johan Myréen
Oct 22 '17 at 19:30
Why is there an effective uid and a real uid ? What does that accomplish? What would be the harm if there was only one uid?
– ng.newbie
Oct 22 '17 at 19:57
|
show 1 more comment
So all processes that need to execute setuid(0) the effective uid needs to be 0 in advance, correct ? Then why isn't the effective uid just used for root operations ? Why callsetuid(0)
again ? I mean any process with effective uid set to 0 will obviously be able to execute setuid(0), so why have a call again the code ?
– ng.newbie
Oct 22 '17 at 18:26
Also is there any way a normal process can set it's eid to 0 so it can successfully callsetuid(0)
?
– ng.newbie
Oct 22 '17 at 18:28
Quoting thesetuid(2)
man page: "setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set." So calling setuid(0) as (effective) root just sets the real uid to 0, too. Not doing this affects for example theaccess(2)
system call, which uses the real uid to do the check.ps
also shows thesu
process as running by root because is shows the real uid. (Btw. theaccess(2)
system call is essentially useless because of race conditions.)
– Johan Myréen
Oct 22 '17 at 18:51
No, there is no way a normal (unprivileged) process can successfully callsetuid(0)
. An unprivileged program can usesetuid()
to change its effective uid, though. If the program is started as suid non-root, the effective uid and the real uid are different. The program can callsetuid()
to set the effective uid to the real uid. A privileged program can usesetuid()
to drop privileges by setting both uids to a value of its own choice.
– Johan Myréen
Oct 22 '17 at 19:30
Why is there an effective uid and a real uid ? What does that accomplish? What would be the harm if there was only one uid?
– ng.newbie
Oct 22 '17 at 19:57
So all processes that need to execute setuid(0) the effective uid needs to be 0 in advance, correct ? Then why isn't the effective uid just used for root operations ? Why call
setuid(0)
again ? I mean any process with effective uid set to 0 will obviously be able to execute setuid(0), so why have a call again the code ?– ng.newbie
Oct 22 '17 at 18:26
So all processes that need to execute setuid(0) the effective uid needs to be 0 in advance, correct ? Then why isn't the effective uid just used for root operations ? Why call
setuid(0)
again ? I mean any process with effective uid set to 0 will obviously be able to execute setuid(0), so why have a call again the code ?– ng.newbie
Oct 22 '17 at 18:26
Also is there any way a normal process can set it's eid to 0 so it can successfully call
setuid(0)
?– ng.newbie
Oct 22 '17 at 18:28
Also is there any way a normal process can set it's eid to 0 so it can successfully call
setuid(0)
?– ng.newbie
Oct 22 '17 at 18:28
Quoting the
setuid(2)
man page: "setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set." So calling setuid(0) as (effective) root just sets the real uid to 0, too. Not doing this affects for example the access(2)
system call, which uses the real uid to do the check. ps
also shows the su
process as running by root because is shows the real uid. (Btw. the access(2)
system call is essentially useless because of race conditions.)– Johan Myréen
Oct 22 '17 at 18:51
Quoting the
setuid(2)
man page: "setuid() sets the effective user ID of the calling process. If the effective UID of the caller is root, the real UID and saved set-user-ID are also set." So calling setuid(0) as (effective) root just sets the real uid to 0, too. Not doing this affects for example the access(2)
system call, which uses the real uid to do the check. ps
also shows the su
process as running by root because is shows the real uid. (Btw. the access(2)
system call is essentially useless because of race conditions.)– Johan Myréen
Oct 22 '17 at 18:51
No, there is no way a normal (unprivileged) process can successfully call
setuid(0)
. An unprivileged program can use setuid()
to change its effective uid, though. If the program is started as suid non-root, the effective uid and the real uid are different. The program can call setuid()
to set the effective uid to the real uid. A privileged program can use setuid()
to drop privileges by setting both uids to a value of its own choice.– Johan Myréen
Oct 22 '17 at 19:30
No, there is no way a normal (unprivileged) process can successfully call
setuid(0)
. An unprivileged program can use setuid()
to change its effective uid, though. If the program is started as suid non-root, the effective uid and the real uid are different. The program can call setuid()
to set the effective uid to the real uid. A privileged program can use setuid()
to drop privileges by setting both uids to a value of its own choice.– Johan Myréen
Oct 22 '17 at 19:30
Why is there an effective uid and a real uid ? What does that accomplish? What would be the harm if there was only one uid?
– ng.newbie
Oct 22 '17 at 19:57
Why is there an effective uid and a real uid ? What does that accomplish? What would be the harm if there was only one uid?
– ng.newbie
Oct 22 '17 at 19:57
|
show 1 more comment
In order for setuid(some_uid) to work, the following conditions need to be met:
- The executable's file needs to be owned by some_uid1.
- The executable's file needs to have the setuid permission.
The setuid permission can be granted or removed with chmod
:
chmod u+s execuables_file_name
chmod u-s execuables_file_name
The setuid permission can be seen when displaying the file permissions as the execute permission will be replaced by an s
if the setuid permission is granted.
> ll execuables_file_name
-rwsrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
If for some reason the owner user doesn't have execute permissions, then it will be displayed as a capital S instead:
> ll execuables_file_name
-rwSrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
Note that scripts are an entirely different beast.
A thorough guide to permissions.
1. setuid(some_uid) will also succeed if transitioning to the user id that started the process
New contributor
add a comment |
In order for setuid(some_uid) to work, the following conditions need to be met:
- The executable's file needs to be owned by some_uid1.
- The executable's file needs to have the setuid permission.
The setuid permission can be granted or removed with chmod
:
chmod u+s execuables_file_name
chmod u-s execuables_file_name
The setuid permission can be seen when displaying the file permissions as the execute permission will be replaced by an s
if the setuid permission is granted.
> ll execuables_file_name
-rwsrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
If for some reason the owner user doesn't have execute permissions, then it will be displayed as a capital S instead:
> ll execuables_file_name
-rwSrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
Note that scripts are an entirely different beast.
A thorough guide to permissions.
1. setuid(some_uid) will also succeed if transitioning to the user id that started the process
New contributor
add a comment |
In order for setuid(some_uid) to work, the following conditions need to be met:
- The executable's file needs to be owned by some_uid1.
- The executable's file needs to have the setuid permission.
The setuid permission can be granted or removed with chmod
:
chmod u+s execuables_file_name
chmod u-s execuables_file_name
The setuid permission can be seen when displaying the file permissions as the execute permission will be replaced by an s
if the setuid permission is granted.
> ll execuables_file_name
-rwsrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
If for some reason the owner user doesn't have execute permissions, then it will be displayed as a capital S instead:
> ll execuables_file_name
-rwSrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
Note that scripts are an entirely different beast.
A thorough guide to permissions.
1. setuid(some_uid) will also succeed if transitioning to the user id that started the process
New contributor
In order for setuid(some_uid) to work, the following conditions need to be met:
- The executable's file needs to be owned by some_uid1.
- The executable's file needs to have the setuid permission.
The setuid permission can be granted or removed with chmod
:
chmod u+s execuables_file_name
chmod u-s execuables_file_name
The setuid permission can be seen when displaying the file permissions as the execute permission will be replaced by an s
if the setuid permission is granted.
> ll execuables_file_name
-rwsrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
If for some reason the owner user doesn't have execute permissions, then it will be displayed as a capital S instead:
> ll execuables_file_name
-rwSrwxr-x 1 root root 0 Sep 30 17:23 execuables_file_name*
Note that scripts are an entirely different beast.
A thorough guide to permissions.
1. setuid(some_uid) will also succeed if transitioning to the user id that started the process
New contributor
New contributor
answered 14 hours ago
RickRick
1011
1011
New contributor
New contributor
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f399746%2fwhat-is-required-by-a-process-to-set-its-uid-to-0-root%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Yes so which user can? Can only a root user invoke this method?
– ng.newbie
Oct 22 '17 at 16:36
If we accept your unproven claim that any process can run as root, that would be a major security hole that has for some reason gone unpatched in the decades unix has been available. A simpler answer is instead that your claim is false; why then would you make such a claim?
– thrig
Oct 22 '17 at 16:59
@thrig What confuses me is that looking at the source for the su binary - you can see that there is a call to
setuid(0)
, so was just wondering how it is possible there. And if it possible there why isn't it possible in other cases ? What prerequisites are needed for the method to successfully execute ? That was my question. I know my claim is false.– ng.newbie
Oct 22 '17 at 17:03
su
has the setuid permission bit set– thrig
Oct 22 '17 at 18:10
@thrig Would you please tell me which permission but needs to be set in order for a successful call to setuid(0) ?
– ng.newbie
Oct 22 '17 at 18:29