On Fri, 2013-04-05 at 15:02 +0200, Lukas Slebodnik wrote:
> On (05/04/13 08:47), Simo Sorce wrote:
> >On Fri, 2013-04-05 at 12:26 +0200, Lukas Slebodnik wrote:
> >> On (04/04/13 12:24), Simo Sorce wrote:
> >> >Commit should say it all.
> >> >We do not have any security issue (that I know off) with the current
> >> >code, but I want to tighten up the privileges more given we do not need
> >> >the additional capabilities in the krb5_child anyway.
> >> >
> >> >Simo.
> >> >
> >> >-- 
> >> >Simo Sorce * Red Hat, Inc * New York
> >> Nack
> >> 
> >> Patch make impossible user authentication.
> >> 
> >> sh-4.2$ su - usersssd02
> >> Password: 
> >> su: incorrect password
> >> 
> >> 
> >> From krb5_child.log:
> >> [become_user] (0x0200): Trying to become user [325600012][325600012].
> >> [create_ccache_in_dir] (0x0200): Creating ccache at 
> >> [DIR:/run/user/325600012/krb5cc]
> >> [become_user] (0x0200): Trying to become user [325600012][325600012].
> >> [become_user] (0x0020): setgroups failed [1][Operation not permitted].
> >>                                    ^^^^^
> >> The second call of function become_user fail with EPERM
> >> 
> >> [create_ccache_in_dir] (0x0020): become_user failed.
> >> [get_and_save_tgt] (0x0020): 1140: [1][Operation not permitted]
> >> [map_krb5_error] (0x0020): 1160: [1][Operation not permitted]
> >> 
> >> > errno_t become_user(uid_t uid, gid_t gid)
> >> > {
> >> >     int ret;
> >> > 
> >> >     DEBUG(SSSDBG_FUNC_DATA, ("Trying to become user [%d][%d].\n", uid, 
> >> > gid));
> >> >-    ret = setgid(gid);
> >> >-    if (ret == -1) {
> >> >-        ret = errno;
> >> >-        DEBUG(SSSDBG_CRIT_FAILURE,
> >> >-              ("setgid failed [%d][%s].\n", ret, strerror(ret)));
> >> >-        return ret;
> >> >-    }
> >> > 
> >> >-    ret = setuid(uid);
> >> >+    /* drop supplmentary groups first */
> >> >+    ret = setgroups(0, NULL);
> >> >     if (ret == -1) {
> >> >         ret = errno;
> >> If errno is EPERM, than we should ignore this error and continue.
> >> 
> >> >         DEBUG(SSSDBG_CRIT_FAILURE,
> >> >-              ("setuid failed [%d][%s].\n", ret, strerror(ret)));
> >> >+              ("setgroups failed [%d][%s].\n", ret, strerror(ret)));
> >> >         return ret;
> >> >     }
> >> > 
> >
> >It is very odd that we get EPERM .. is this function beeing called
> >twice ? Once as root before the fork, and then again in the code ?
> >
> >Simo.
> 
> Yes twice.
> 
> 1st call:
> --------------------------------------------
> #0  become_user (uid=325600012, gid=325600012)
>     at src/providers/krb5/krb5_become_user.c:29
> #1  0x00000000004101dd in get_and_save_tgt (kr=kr@entry=0x227f090, 
>     password=<optimized out>) at src/providers/krb5/krb5_child.c:1128
> #2  0x0000000000407972 in tgt_req_child (kr=0x227f090)
>     at src/providers/krb5/krb5_child.c:1337
> #3  main (argc=<optimized out>, argv=<optimized out>)
>     at src/providers/krb5/krb5_child.c:2126
> 
> 
> 2nd call:
> --------------------------------------------
> #0  become_user (uid=uid@entry=325600012, gid=gid@entry=325600012)
>     at src/providers/krb5/krb5_become_user.c:29
> #1  0x000000000040b569 in create_ccache_in_dir (uid=uid@entry=325600012, 
>     gid=gid@entry=325600012, ctx=ctx@entry=0x2280010, 
>     princ=princ@entry=0x2287760, 
>     ccname=ccname@entry=0x227f280 "DIR:/run/user/325600012/krb5cc", 
>     creds=creds@entry=0x22807a0) at src/providers/krb5/krb5_child.c:659
> #2  0x000000000040eb7c in create_ccache (uid=325600012, gid=325600012, 
>     ctx=0x2280010, princ=0x2287760, 
>     ccname=0x227f280 "DIR:/run/user/325600012/krb5cc", creds=0x22807a0)
>     at src/providers/krb5/krb5_child.c:732
> #3  0x000000000041020a in get_and_save_tgt (kr=kr@entry=0x227f090, 
>     password=<optimized out>) at src/providers/krb5/krb5_child.c:1136
> #4  0x0000000000407972 in tgt_req_child (kr=0x227f090)
>     at src/providers/krb5/krb5_child.c:1337
> #5  main (argc=<optimized out>, argv=<optimized out>)
>     at src/providers/krb5/krb5_child.c:2126

Ok, attached augmented patch should handle this case too.

Thanks for testing.

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York
>From 1719aa02504afa1c98f3227966ab0394e81bc50b Mon Sep 17 00:00:00 2001
From: Simo Sorce <s...@redhat.com>
Date: Thu, 4 Apr 2013 11:32:51 -0400
Subject: [PATCH] Further restrict become_user drop of privileges.

We never need to regain root after we call become_user() so tighten up even
further our privilege drop.

Add a setgroups() call to remove all secondary groups root may have been given
for whateve reason. Then use the setres[ug]id function to also drop the saved
uid/gid so the process cannot regain back root id.
Capabilities are also implicitly dropped here, no more CAP_SETUID so this is a
Point of No Return, once changed to non-root the process can't get back.

Remove redefinition of sys/types.h and unistd.h, they are already defined in
util.h and they need to be included after _GNU_SOURCE/_BSD_SOURCE is defined
or the prototypes for setres[ug]id will not be found.
Add grp.h after util.h for the same reason.
---
 src/providers/krb5/krb5_become_user.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/src/providers/krb5/krb5_become_user.c b/src/providers/krb5/krb5_become_user.c
index 082d141534cd12a02ee8a0ed5fa66114e7adfc73..70bc5630ece21505b58bd1a8795d7ab4b7864460 100644
--- a/src/providers/krb5/krb5_become_user.c
+++ b/src/providers/krb5/krb5_become_user.c
@@ -22,45 +22,48 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <sys/types.h>
-#include <unistd.h>
-
 #include "util/util.h"
+#include <grp.h>
 
 errno_t become_user(uid_t uid, gid_t gid)
 {
+    uid_t cuid;
     int ret;
 
     DEBUG(SSSDBG_FUNC_DATA, ("Trying to become user [%d][%d].\n", uid, gid));
-    ret = setgid(gid);
-    if (ret == -1) {
-        ret = errno;
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              ("setgid failed [%d][%s].\n", ret, strerror(ret)));
-        return ret;
+
+    /* skip call if we already are the requested user */
+    cuid = geteuid();
+    if (uid == cuid) {
+        DEBUG(SSSDBG_FUNC_DATA, ("Already user [%d].\n", uid));
+        return EOK;
     }
 
-    ret = setuid(uid);
+    /* drop supplmentary groups first */
+    ret = setgroups(0, NULL);
     if (ret == -1) {
         ret = errno;
         DEBUG(SSSDBG_CRIT_FAILURE,
-              ("setuid failed [%d][%s].\n", ret, strerror(ret)));
+              ("setgroups failed [%d][%s].\n", ret, strerror(ret)));
         return ret;
     }
 
-    ret = setegid(gid);
+    /* change gid so that root cannot be regained (changes saved gid too) */
+    ret = setresgid(gid, gid, gid);
     if (ret == -1) {
         ret = errno;
         DEBUG(SSSDBG_CRIT_FAILURE,
-              ("setegid failed [%d][%s].\n", ret, strerror(ret)));
+              ("setresgid failed [%d][%s].\n", ret, strerror(ret)));
         return ret;
     }
 
-    ret = seteuid(uid);
+    /* change uid so that root cannot be regained (changes saved uid too) */
+    /* this call also takes care of dropping CAP_SETUID, so this is a PNR */
+    ret = setresuid(uid, uid, uid);
     if (ret == -1) {
         ret = errno;
         DEBUG(SSSDBG_CRIT_FAILURE,
-              ("seteuid failed [%d][%s].\n", ret, strerror(ret)));
+              ("setresuid failed [%d][%s].\n", ret, strerror(ret)));
         return ret;
     }
 
-- 
1.8.1.4

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to