Re: Documenting execve() and EAGAIN
Hello Vasiliy, On 05/26/2014 08:11 PM, Vasiliy Kulikov wrote: > Hi Michael, > > On Wed, May 21, 2014 at 20:12 +0200, Michael Kerrisk (man-pages) wrote: >> Vasily (and Motohiro), >> >> Sometime ago, Motohiro raised a documentation bug >> ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which >> relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c >> ("move RLIMIT_NPROC check from set_user() to do_execve_common()") >> >> I have attempted to document this, and I would like to ask you >> (and Motohiro) if you would review the text proposed below for >> the exceve(2) man page. >> >> Thank you, >> >> Michael >> >> >> ERRORS >>EAGAIN (since Linux 3.1) >> Having changed its real UID using one of the set*uid() >> calls, the caller was—and is now still—above its >> RLIMIT_NPROC resource limit (see setrlimit(2)). For a >> more detailed explanation of this error, see NOTES. >> >> NOTES >>execve() and EAGAIN >>A more detailed explanation of the EAGAIN error that can occur >>(since Linux 3.1) when calling execve() is as follows. >> >>The EAGAIN error can occur when a preceding call to setuid(2), >>setreuid(2), or setresuid(2) caused the real user ID of the >>process to change, and that change caused the process to >>exceed its RLIMIT_NPROC resource limit (i.e., the number of >>processes belonging to the new real UID exceeds the resource >>limit). In Linux 3.0 and earlier, this caused the set*uid() >>call to fail. >> >>Since Linux 3.1, the scenario just described no longer causes >>the set*uid() call to fail, because it too often led to secu‐ >>rity holes because buggy applications didn't check the return >>status and assumed that—if the caller had root privileges—the >>call would always succeed. Instead, the set*uid() calls now >>successfully change real UID, but the kernel sets an internal >>flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC >>resource limit has been exceeded. If the resource limit is >>still exceeded at the time of a subsequent execve() call, that >>call fails with the error EAGAIN. This kernel logic ensures >>that the RLIMIT_NPROC resource limit is still enforced for the >>common privileged daemon workflow—namely, fork(2)+ set*uid()+ >>execve(2). >> >>If the resource limit was not still exceeded at the time of >>the execve() call (because other processes belonging to this >>real UID terminated between the set*uid() call and the >>execve() call), then the execve() call succeeds and the kernel >>clears the PF_NPROC_EXCEEDED process flag. The flag is also >>cleared if a subsequent call to fork(2) by this process suc‐ >>ceeds. > > Probably explicitly state that NPROC check on execve() is processed only > in case of a previous set*uid() call? If there was no previous > set*uid() call the semantics of execve() checks are the same as before > (IOW, RLIMIT_NPROC is ignored). Yes, good idea. I'll add some words to make that clearer. > The rest is fine. Thanks for checking it! Cheers, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Documenting execve() and EAGAIN
Hi Michael, On Wed, May 21, 2014 at 20:12 +0200, Michael Kerrisk (man-pages) wrote: > Vasily (and Motohiro), > > Sometime ago, Motohiro raised a documentation bug > ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which > relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c > ("move RLIMIT_NPROC check from set_user() to do_execve_common()") > > I have attempted to document this, and I would like to ask you > (and Motohiro) if you would review the text proposed below for > the exceve(2) man page. > > Thank you, > > Michael > > > ERRORS >EAGAIN (since Linux 3.1) > Having changed its real UID using one of the set*uid() > calls, the caller was—and is now still—above its > RLIMIT_NPROC resource limit (see setrlimit(2)). For a > more detailed explanation of this error, see NOTES. > > NOTES >execve() and EAGAIN >A more detailed explanation of the EAGAIN error that can occur >(since Linux 3.1) when calling execve() is as follows. > >The EAGAIN error can occur when a preceding call to setuid(2), >setreuid(2), or setresuid(2) caused the real user ID of the >process to change, and that change caused the process to >exceed its RLIMIT_NPROC resource limit (i.e., the number of >processes belonging to the new real UID exceeds the resource >limit). In Linux 3.0 and earlier, this caused the set*uid() >call to fail. > >Since Linux 3.1, the scenario just described no longer causes >the set*uid() call to fail, because it too often led to secu‐ >rity holes because buggy applications didn't check the return >status and assumed that—if the caller had root privileges—the >call would always succeed. Instead, the set*uid() calls now >successfully change real UID, but the kernel sets an internal >flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC >resource limit has been exceeded. If the resource limit is >still exceeded at the time of a subsequent execve() call, that >call fails with the error EAGAIN. This kernel logic ensures >that the RLIMIT_NPROC resource limit is still enforced for the >common privileged daemon workflow—namely, fork(2)+ set*uid()+ >execve(2). > >If the resource limit was not still exceeded at the time of >the execve() call (because other processes belonging to this >real UID terminated between the set*uid() call and the >execve() call), then the execve() call succeeds and the kernel >clears the PF_NPROC_EXCEEDED process flag. The flag is also >cleared if a subsequent call to fork(2) by this process suc‐ >ceeds. Probably explicitly state that NPROC check on execve() is processed only in case of a previous set*uid() call? If there was no previous set*uid() call the semantics of execve() checks are the same as before (IOW, RLIMIT_NPROC is ignored). The rest is fine. Thanks! -- Vasily Kulikov http://www.openwall.com - bringing security into open computing environments -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Documenting execve() and EAGAIN
Hi Michael, On Wed, May 21, 2014 at 20:12 +0200, Michael Kerrisk (man-pages) wrote: Vasily (and Motohiro), Sometime ago, Motohiro raised a documentation bug ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c (move RLIMIT_NPROC check from set_user() to do_execve_common()) I have attempted to document this, and I would like to ask you (and Motohiro) if you would review the text proposed below for the exceve(2) man page. Thank you, Michael ERRORS EAGAIN (since Linux 3.1) Having changed its real UID using one of the set*uid() calls, the caller was—and is now still—above its RLIMIT_NPROC resource limit (see setrlimit(2)). For a more detailed explanation of this error, see NOTES. NOTES execve() and EAGAIN A more detailed explanation of the EAGAIN error that can occur (since Linux 3.1) when calling execve() is as follows. The EAGAIN error can occur when a preceding call to setuid(2), setreuid(2), or setresuid(2) caused the real user ID of the process to change, and that change caused the process to exceed its RLIMIT_NPROC resource limit (i.e., the number of processes belonging to the new real UID exceeds the resource limit). In Linux 3.0 and earlier, this caused the set*uid() call to fail. Since Linux 3.1, the scenario just described no longer causes the set*uid() call to fail, because it too often led to secu‐ rity holes because buggy applications didn't check the return status and assumed that—if the caller had root privileges—the call would always succeed. Instead, the set*uid() calls now successfully change real UID, but the kernel sets an internal flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC resource limit has been exceeded. If the resource limit is still exceeded at the time of a subsequent execve() call, that call fails with the error EAGAIN. This kernel logic ensures that the RLIMIT_NPROC resource limit is still enforced for the common privileged daemon workflow—namely, fork(2)+ set*uid()+ execve(2). If the resource limit was not still exceeded at the time of the execve() call (because other processes belonging to this real UID terminated between the set*uid() call and the execve() call), then the execve() call succeeds and the kernel clears the PF_NPROC_EXCEEDED process flag. The flag is also cleared if a subsequent call to fork(2) by this process suc‐ ceeds. Probably explicitly state that NPROC check on execve() is processed only in case of a previous set*uid() call? If there was no previous set*uid() call the semantics of execve() checks are the same as before (IOW, RLIMIT_NPROC is ignored). The rest is fine. Thanks! -- Vasily Kulikov http://www.openwall.com - bringing security into open computing environments -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Documenting execve() and EAGAIN
Hello Vasiliy, On 05/26/2014 08:11 PM, Vasiliy Kulikov wrote: Hi Michael, On Wed, May 21, 2014 at 20:12 +0200, Michael Kerrisk (man-pages) wrote: Vasily (and Motohiro), Sometime ago, Motohiro raised a documentation bug ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c (move RLIMIT_NPROC check from set_user() to do_execve_common()) I have attempted to document this, and I would like to ask you (and Motohiro) if you would review the text proposed below for the exceve(2) man page. Thank you, Michael ERRORS EAGAIN (since Linux 3.1) Having changed its real UID using one of the set*uid() calls, the caller was—and is now still—above its RLIMIT_NPROC resource limit (see setrlimit(2)). For a more detailed explanation of this error, see NOTES. NOTES execve() and EAGAIN A more detailed explanation of the EAGAIN error that can occur (since Linux 3.1) when calling execve() is as follows. The EAGAIN error can occur when a preceding call to setuid(2), setreuid(2), or setresuid(2) caused the real user ID of the process to change, and that change caused the process to exceed its RLIMIT_NPROC resource limit (i.e., the number of processes belonging to the new real UID exceeds the resource limit). In Linux 3.0 and earlier, this caused the set*uid() call to fail. Since Linux 3.1, the scenario just described no longer causes the set*uid() call to fail, because it too often led to secu‐ rity holes because buggy applications didn't check the return status and assumed that—if the caller had root privileges—the call would always succeed. Instead, the set*uid() calls now successfully change real UID, but the kernel sets an internal flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC resource limit has been exceeded. If the resource limit is still exceeded at the time of a subsequent execve() call, that call fails with the error EAGAIN. This kernel logic ensures that the RLIMIT_NPROC resource limit is still enforced for the common privileged daemon workflow—namely, fork(2)+ set*uid()+ execve(2). If the resource limit was not still exceeded at the time of the execve() call (because other processes belonging to this real UID terminated between the set*uid() call and the execve() call), then the execve() call succeeds and the kernel clears the PF_NPROC_EXCEEDED process flag. The flag is also cleared if a subsequent call to fork(2) by this process suc‐ ceeds. Probably explicitly state that NPROC check on execve() is processed only in case of a previous set*uid() call? If there was no previous set*uid() call the semantics of execve() checks are the same as before (IOW, RLIMIT_NPROC is ignored). Yes, good idea. I'll add some words to make that clearer. The rest is fine. Thanks for checking it! Cheers, Michael -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Documenting execve() and EAGAIN
On Thu, May 22, 2014 at 3:41 AM, NeilBrown wrote: > On Wed, 21 May 2014 20:12:32 +0200 "Michael Kerrisk (man-pages)" > wrote: > >> Vasily (and Motohiro), >> >> Sometime ago, Motohiro raised a documentation bug >> ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which >> relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c >> ("move RLIMIT_NPROC check from set_user() to do_execve_common()") >> >> I have attempted to document this, and I would like to ask you >> (and Motohiro) if you would review the text proposed below for >> the exceve(2) man page. >> >> Thank you, >> >> Michael >> >> >> ERRORS >>EAGAIN (since Linux 3.1) >> Having changed its real UID using one of the set*uid() >> calls, the caller was—and is now still—above its >> RLIMIT_NPROC resource limit (see setrlimit(2)). For a >> more detailed explanation of this error, see NOTES. >> >> NOTES >>execve() and EAGAIN >>A more detailed explanation of the EAGAIN error that can occur >>(since Linux 3.1) when calling execve() is as follows. >> >>The EAGAIN error can occur when a preceding call to setuid(2), >>setreuid(2), or setresuid(2) caused the real user ID of the >>process to change, and that change caused the process to >>exceed its RLIMIT_NPROC resource limit (i.e., the number of >>processes belonging to the new real UID exceeds the resource >>limit). In Linux 3.0 and earlier, this caused the set*uid() >>call to fail. > > I don't know how detailed/precise you want to be, but this failure was from > 2.6.0 to 3.0. > Prior to 2.6, the limit was not imposed on processes that changed their uid. > > http://git.kernel.org/cgit/linux/kernel/git/history/history.git/commit/?id=909cc4ae86f3380152a18e2a3c44523893ee11c4 > > $ git describe --contains 909cc4ae86f3380152a18e2a3c44523893ee11c4 > v2.6.0-test2~85^2~5^2~15 > > Otherwise the description fits my understanding. Thanks Neil, I've added the details you mention to the draft. Cheers, Michael >> >>Since Linux 3.1, the scenario just described no longer causes >>the set*uid() call to fail, because it too often led to secu‐ >>rity holes because buggy applications didn't check the return >>status and assumed that—if the caller had root privileges—the >>call would always succeed. Instead, the set*uid() calls now >>successfully change real UID, but the kernel sets an internal >>flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC >>resource limit has been exceeded. If the resource limit is >>still exceeded at the time of a subsequent execve() call, that >>call fails with the error EAGAIN. This kernel logic ensures >>that the RLIMIT_NPROC resource limit is still enforced for the >>common privileged daemon workflow—namely, fork(2)+ set*uid()+ >>execve(2). >> >>If the resource limit was not still exceeded at the time of >>the execve() call (because other processes belonging to this >>real UID terminated between the set*uid() call and the >>execve() call), then the execve() call succeeds and the kernel >>clears the PF_NPROC_EXCEEDED process flag. The flag is also >>cleared if a subsequent call to fork(2) by this process suc‐ >>ceeds. >> > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Documenting execve() and EAGAIN
On Thu, May 22, 2014 at 3:41 AM, NeilBrown ne...@suse.de wrote: On Wed, 21 May 2014 20:12:32 +0200 Michael Kerrisk (man-pages) mtk.manpa...@gmail.com wrote: Vasily (and Motohiro), Sometime ago, Motohiro raised a documentation bug ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c (move RLIMIT_NPROC check from set_user() to do_execve_common()) I have attempted to document this, and I would like to ask you (and Motohiro) if you would review the text proposed below for the exceve(2) man page. Thank you, Michael ERRORS EAGAIN (since Linux 3.1) Having changed its real UID using one of the set*uid() calls, the caller was—and is now still—above its RLIMIT_NPROC resource limit (see setrlimit(2)). For a more detailed explanation of this error, see NOTES. NOTES execve() and EAGAIN A more detailed explanation of the EAGAIN error that can occur (since Linux 3.1) when calling execve() is as follows. The EAGAIN error can occur when a preceding call to setuid(2), setreuid(2), or setresuid(2) caused the real user ID of the process to change, and that change caused the process to exceed its RLIMIT_NPROC resource limit (i.e., the number of processes belonging to the new real UID exceeds the resource limit). In Linux 3.0 and earlier, this caused the set*uid() call to fail. I don't know how detailed/precise you want to be, but this failure was from 2.6.0 to 3.0. Prior to 2.6, the limit was not imposed on processes that changed their uid. http://git.kernel.org/cgit/linux/kernel/git/history/history.git/commit/?id=909cc4ae86f3380152a18e2a3c44523893ee11c4 $ git describe --contains 909cc4ae86f3380152a18e2a3c44523893ee11c4 v2.6.0-test2~85^2~5^2~15 Otherwise the description fits my understanding. Thanks Neil, I've added the details you mention to the draft. Cheers, Michael Since Linux 3.1, the scenario just described no longer causes the set*uid() call to fail, because it too often led to secu‐ rity holes because buggy applications didn't check the return status and assumed that—if the caller had root privileges—the call would always succeed. Instead, the set*uid() calls now successfully change real UID, but the kernel sets an internal flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC resource limit has been exceeded. If the resource limit is still exceeded at the time of a subsequent execve() call, that call fails with the error EAGAIN. This kernel logic ensures that the RLIMIT_NPROC resource limit is still enforced for the common privileged daemon workflow—namely, fork(2)+ set*uid()+ execve(2). If the resource limit was not still exceeded at the time of the execve() call (because other processes belonging to this real UID terminated between the set*uid() call and the execve() call), then the execve() call succeeds and the kernel clears the PF_NPROC_EXCEEDED process flag. The flag is also cleared if a subsequent call to fork(2) by this process suc‐ ceeds. -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Documenting execve() and EAGAIN
On Wed, 21 May 2014 20:12:32 +0200 "Michael Kerrisk (man-pages)" wrote: > Vasily (and Motohiro), > > Sometime ago, Motohiro raised a documentation bug > ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which > relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c > ("move RLIMIT_NPROC check from set_user() to do_execve_common()") > > I have attempted to document this, and I would like to ask you > (and Motohiro) if you would review the text proposed below for > the exceve(2) man page. > > Thank you, > > Michael > > > ERRORS >EAGAIN (since Linux 3.1) > Having changed its real UID using one of the set*uid() > calls, the caller was—and is now still—above its > RLIMIT_NPROC resource limit (see setrlimit(2)). For a > more detailed explanation of this error, see NOTES. > > NOTES >execve() and EAGAIN >A more detailed explanation of the EAGAIN error that can occur >(since Linux 3.1) when calling execve() is as follows. > >The EAGAIN error can occur when a preceding call to setuid(2), >setreuid(2), or setresuid(2) caused the real user ID of the >process to change, and that change caused the process to >exceed its RLIMIT_NPROC resource limit (i.e., the number of >processes belonging to the new real UID exceeds the resource >limit). In Linux 3.0 and earlier, this caused the set*uid() >call to fail. I don't know how detailed/precise you want to be, but this failure was from 2.6.0 to 3.0. Prior to 2.6, the limit was not imposed on processes that changed their uid. http://git.kernel.org/cgit/linux/kernel/git/history/history.git/commit/?id=909cc4ae86f3380152a18e2a3c44523893ee11c4 $ git describe --contains 909cc4ae86f3380152a18e2a3c44523893ee11c4 v2.6.0-test2~85^2~5^2~15 Otherwise the description fits my understanding. NeilBrown > >Since Linux 3.1, the scenario just described no longer causes >the set*uid() call to fail, because it too often led to secu‐ >rity holes because buggy applications didn't check the return >status and assumed that—if the caller had root privileges—the >call would always succeed. Instead, the set*uid() calls now >successfully change real UID, but the kernel sets an internal >flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC >resource limit has been exceeded. If the resource limit is >still exceeded at the time of a subsequent execve() call, that >call fails with the error EAGAIN. This kernel logic ensures >that the RLIMIT_NPROC resource limit is still enforced for the >common privileged daemon workflow—namely, fork(2)+ set*uid()+ >execve(2). > >If the resource limit was not still exceeded at the time of >the execve() call (because other processes belonging to this >real UID terminated between the set*uid() call and the >execve() call), then the execve() call succeeds and the kernel >clears the PF_NPROC_EXCEEDED process flag. The flag is also >cleared if a subsequent call to fork(2) by this process suc‐ >ceeds. > signature.asc Description: PGP signature
Documenting execve() and EAGAIN
Vasily (and Motohiro), Sometime ago, Motohiro raised a documentation bug ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c ("move RLIMIT_NPROC check from set_user() to do_execve_common()") I have attempted to document this, and I would like to ask you (and Motohiro) if you would review the text proposed below for the exceve(2) man page. Thank you, Michael ERRORS EAGAIN (since Linux 3.1) Having changed its real UID using one of the set*uid() calls, the caller was—and is now still—above its RLIMIT_NPROC resource limit (see setrlimit(2)). For a more detailed explanation of this error, see NOTES. NOTES execve() and EAGAIN A more detailed explanation of the EAGAIN error that can occur (since Linux 3.1) when calling execve() is as follows. The EAGAIN error can occur when a preceding call to setuid(2), setreuid(2), or setresuid(2) caused the real user ID of the process to change, and that change caused the process to exceed its RLIMIT_NPROC resource limit (i.e., the number of processes belonging to the new real UID exceeds the resource limit). In Linux 3.0 and earlier, this caused the set*uid() call to fail. Since Linux 3.1, the scenario just described no longer causes the set*uid() call to fail, because it too often led to secu‐ rity holes because buggy applications didn't check the return status and assumed that—if the caller had root privileges—the call would always succeed. Instead, the set*uid() calls now successfully change real UID, but the kernel sets an internal flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC resource limit has been exceeded. If the resource limit is still exceeded at the time of a subsequent execve() call, that call fails with the error EAGAIN. This kernel logic ensures that the RLIMIT_NPROC resource limit is still enforced for the common privileged daemon workflow—namely, fork(2)+ set*uid()+ execve(2). If the resource limit was not still exceeded at the time of the execve() call (because other processes belonging to this real UID terminated between the set*uid() call and the execve() call), then the execve() call succeeds and the kernel clears the PF_NPROC_EXCEEDED process flag. The flag is also cleared if a subsequent call to fork(2) by this process suc‐ ceeds. -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Documenting execve() and EAGAIN
Vasily (and Motohiro), Sometime ago, Motohiro raised a documentation bug ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c (move RLIMIT_NPROC check from set_user() to do_execve_common()) I have attempted to document this, and I would like to ask you (and Motohiro) if you would review the text proposed below for the exceve(2) man page. Thank you, Michael ERRORS EAGAIN (since Linux 3.1) Having changed its real UID using one of the set*uid() calls, the caller was—and is now still—above its RLIMIT_NPROC resource limit (see setrlimit(2)). For a more detailed explanation of this error, see NOTES. NOTES execve() and EAGAIN A more detailed explanation of the EAGAIN error that can occur (since Linux 3.1) when calling execve() is as follows. The EAGAIN error can occur when a preceding call to setuid(2), setreuid(2), or setresuid(2) caused the real user ID of the process to change, and that change caused the process to exceed its RLIMIT_NPROC resource limit (i.e., the number of processes belonging to the new real UID exceeds the resource limit). In Linux 3.0 and earlier, this caused the set*uid() call to fail. Since Linux 3.1, the scenario just described no longer causes the set*uid() call to fail, because it too often led to secu‐ rity holes because buggy applications didn't check the return status and assumed that—if the caller had root privileges—the call would always succeed. Instead, the set*uid() calls now successfully change real UID, but the kernel sets an internal flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC resource limit has been exceeded. If the resource limit is still exceeded at the time of a subsequent execve() call, that call fails with the error EAGAIN. This kernel logic ensures that the RLIMIT_NPROC resource limit is still enforced for the common privileged daemon workflow—namely, fork(2)+ set*uid()+ execve(2). If the resource limit was not still exceeded at the time of the execve() call (because other processes belonging to this real UID terminated between the set*uid() call and the execve() call), then the execve() call succeeds and the kernel clears the PF_NPROC_EXCEEDED process flag. The flag is also cleared if a subsequent call to fork(2) by this process suc‐ ceeds. -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/ -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: Documenting execve() and EAGAIN
On Wed, 21 May 2014 20:12:32 +0200 Michael Kerrisk (man-pages) mtk.manpa...@gmail.com wrote: Vasily (and Motohiro), Sometime ago, Motohiro raised a documentation bug ( https://bugzilla.kernel.org/show_bug.cgi?id=42704 ) which relates to your commit 72fa59970f8698023045ab0713d66f3f4f96945c (move RLIMIT_NPROC check from set_user() to do_execve_common()) I have attempted to document this, and I would like to ask you (and Motohiro) if you would review the text proposed below for the exceve(2) man page. Thank you, Michael ERRORS EAGAIN (since Linux 3.1) Having changed its real UID using one of the set*uid() calls, the caller was—and is now still—above its RLIMIT_NPROC resource limit (see setrlimit(2)). For a more detailed explanation of this error, see NOTES. NOTES execve() and EAGAIN A more detailed explanation of the EAGAIN error that can occur (since Linux 3.1) when calling execve() is as follows. The EAGAIN error can occur when a preceding call to setuid(2), setreuid(2), or setresuid(2) caused the real user ID of the process to change, and that change caused the process to exceed its RLIMIT_NPROC resource limit (i.e., the number of processes belonging to the new real UID exceeds the resource limit). In Linux 3.0 and earlier, this caused the set*uid() call to fail. I don't know how detailed/precise you want to be, but this failure was from 2.6.0 to 3.0. Prior to 2.6, the limit was not imposed on processes that changed their uid. http://git.kernel.org/cgit/linux/kernel/git/history/history.git/commit/?id=909cc4ae86f3380152a18e2a3c44523893ee11c4 $ git describe --contains 909cc4ae86f3380152a18e2a3c44523893ee11c4 v2.6.0-test2~85^2~5^2~15 Otherwise the description fits my understanding. NeilBrown Since Linux 3.1, the scenario just described no longer causes the set*uid() call to fail, because it too often led to secu‐ rity holes because buggy applications didn't check the return status and assumed that—if the caller had root privileges—the call would always succeed. Instead, the set*uid() calls now successfully change real UID, but the kernel sets an internal flag, named PF_NPROC_EXCEEDED, to note that the RLIMIT_NPROC resource limit has been exceeded. If the resource limit is still exceeded at the time of a subsequent execve() call, that call fails with the error EAGAIN. This kernel logic ensures that the RLIMIT_NPROC resource limit is still enforced for the common privileged daemon workflow—namely, fork(2)+ set*uid()+ execve(2). If the resource limit was not still exceeded at the time of the execve() call (because other processes belonging to this real UID terminated between the set*uid() call and the execve() call), then the execve() call succeeds and the kernel clears the PF_NPROC_EXCEEDED process flag. The flag is also cleared if a subsequent call to fork(2) by this process suc‐ ceeds. signature.asc Description: PGP signature