--- sysklogd-1.4.1/klogd.c.orig 2006-10-12 01:29:49.000000000 +0100 +++ sysklogd-1.4.1/klogd.c 2006-10-12 01:32:58.000000000 +0100 @@ -246,6 +246,9 @@ * Thu Apr 29 15:24:07 2004: Solar Designer * Prevent potential buffer overflow in reading messages from the * kernel log rinbuffer. + * + * Thu Oct 12 00:12:02 2006: Miguel Filipe + * fix drop_root() to work correctly with capabilities */ @@ -263,6 +266,8 @@ #include #include #include +#include +#include #include "klogd.h" #include "ksyms.h" #ifndef TESTING @@ -989,6 +994,9 @@ static int drop_root(void) { struct passwd *pw; + cap_t cap; + cap_value_t cap_value[2] = { CAP_SYS_ADMIN, CAP_SYS_CHROOT }; + int result; if (!(pw = getpwnam(server_user))) return -1; @@ -999,10 +1007,36 @@ if (chdir("/")) return -1; } + /* set keep capabilities */ + if( prctl( PR_SET_KEEPCAPS, 1, 0, 0, 0 ) ) + return -1; + + /* test whether cap_set_proc works */ + cap = cap_get_proc(); + if( cap ) { + result = cap_set_proc( cap ); + cap_free( cap ); + if( result ) + return -1; + } else + return -1; + + if (setgroups(0, NULL)) return -1; if (setgid(pw->pw_gid)) return -1; if (setuid(pw->pw_uid)) return -1; + /* set necessary capabilities */ + cap = cap_init(); + if( cap_set_flag( cap, CAP_PERMITTED, 2, cap_value, CAP_SET ) || + cap_set_flag( cap, CAP_EFFECTIVE, 2, cap_value, CAP_SET ) ) + return -1; + + if( cap_set_proc( cap ) ) + return -1; + if( cap_free( cap ) ) + return -1; + return 0; }