Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 I've pushed it to a pamcap-enhancements branch and I'll will try to review it quickly. Thanks Andrew KaiGai Kohei wrote: > Sorry, any TABs are replaced by MUA. > I'll send the patch again. > >> The attached patch provides several improvement for pam_cap module. >> 1. It enables pam_cap to drop capabilities from process'es capability >>bounding set. >> 2. It enables to specify allowing inheritable capability set or dropping >>bounding capability set for groups, not only users. >> 3. It provide pam_sm_session() method, not only pam_sm_authenticate() >>and pam_sm_setcred(). A system administrator can select more >>appropriate mode for his purpose. >> 4. In the auth/cred mode, it enables to cache the configuration file, >>to avoid read and analyze it twice. >> (Therefore, most of the part in the original one got replaced) >> >> The default configuration file is "/etc/security/capability.conf". >> You can describe as follows: >> >> # kaigai get cap_net_raw and cap_kill, tak get cap_sys_pacct pI. >> # We can omit "i:" in the head of each line. >> i:cap_net_raw,cap_kill kaigai >> cap_sys_pacct tak >> >> # ymj and tak lost cap_sys_chroot from cap_bset >> b:cap_sys_chroot ymj tak >> >> # Any user within webadm group get cap_net_bind_service pI. >> i:cap_net_bind_service @webadm >> >> # Any user within users group lost cap_sys_module from cap_bset >> b:cap_sys_module @users >> >> >> When a user or groups he belongs is on several lines, all configurations >> are simplly compounded. >> >> In the above example, if tak belongs to webadm and users group, >> he will get cap_sys_pacct and cap_net_bind_service pI, and lost >> cap_sys_chroot and cap_sys_module from his cap_bset. >> >> Thanks, > > Signed-off-by: KaiGai Kohei <[EMAIL PROTECTED]> > -- > pam_cap/capability.conf |6 + > pam_cap/pam_cap.c | 495 > --- > 2 files changed, 305 insertions(+), 196 deletions(-) > > diff --git a/pam_cap/capability.conf b/pam_cap/capability.conf > index b543142..707cdc3 100644 > --- a/pam_cap/capability.conf > +++ b/pam_cap/capability.conf > @@ -24,6 +24,12 @@ cap_setfcapmorgan > ## 'everyone else' gets no inheritable capabilities > none * > > +# user 'kaigai' lost CAP_NET_RAW capability from bounding set > +b:cap_net_raw kaigai > + > +# group 'acctadm' get CAP_SYS_PACCT inheritable capability > +i:cap_sys_pacct @acctadm > + > ## if there is no '*' entry, all users not explicitly mentioned will > ## get all available capabilities. This is a permissive default, and > ## probably not what you want... > diff --git a/pam_cap/pam_cap.c b/pam_cap/pam_cap.c > index 94c5ebc..a917d5c 100644 > --- a/pam_cap/pam_cap.c > +++ b/pam_cap/pam_cap.c > @@ -1,5 +1,6 @@ > /* > * Copyright (c) 1999,2007 Andrew G. Morgan <[EMAIL PROTECTED]> > + * Copyright (c) 2007 KaiGai Kohei <[EMAIL PROTECTED]> > * > * The purpose of this module is to enforce inheritable capability sets > * for a specified user. > @@ -13,298 +14,400 @@ > #include > #include > #include > +#include > +#include > > #include > +#include > > #include > #include > > +#define MODULE_NAME "pam_cap" > #define USER_CAP_FILE "/etc/security/capability.conf" > #define CAP_FILE_BUFFER_SIZE4096 > #define CAP_FILE_DELIMITERS " \t\n" > -#define CAP_COMBINED_FORMAT "%s all-i %s+i" > -#define CAP_DROP_ALL"%s all-i" > + > +#ifndef PR_CAPBSET_DROP > +#define PR_CAPBSET_DROP 24 > +#endif > + > +extern char const *_cap_names[]; > > struct pam_cap_s { > int debug; > const char *user; > const char *conf_filename; > +/* set in read_capabilities_for_user() */ > +cap_t result; > +int do_set_inh : 1; > +int do_set_bset : 1; > }; > > -/* obtain the inheritable capabilities for the current user */ > - > -static char *read_capabilities_for_user(const char *user, const char *source) > +/* obtain the inheritable/bounding capabilities for the current user */ > +static int read_capabilities_for_user(struct pam_cap_s *pcs) > { > -char *cap_string = NULL; > -char buffer[CAP_FILE_BUFFER_SIZE], *line; > +char buffer[CAP_FILE_BUFFER_SIZE]; > FILE *cap_file; > +struct passwd *pwd; > +int line_num = 0; > +int rc = -1; /* PAM_(AUTH|CRED|SESSION)_ERR */ > + > +pwd = getpwnam(pcs->user); > +if (!pwd) { > + syslog(LOG_ERR, "user %s not in passwd entries", pcs->user); > + return PAM_AUTH_ERR; > +} > > -cap_file = fopen(source, "r"); > -if (cap_file == NULL) { > - D(("failed to open capability file")); > - return NULL; > +cap_file = fopen(pcs->conf_filename, "r"); > +if (!cap_file) { > + if (errno == ENOENT) { > + syslog(LOG_NOTICE, "%s is not found", > +
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Sorry, any TABs are replaced by MUA. I'll send the patch again. > The attached patch provides several improvement for pam_cap module. > 1. It enables pam_cap to drop capabilities from process'es capability >bounding set. > 2. It enables to specify allowing inheritable capability set or dropping >bounding capability set for groups, not only users. > 3. It provide pam_sm_session() method, not only pam_sm_authenticate() >and pam_sm_setcred(). A system administrator can select more >appropriate mode for his purpose. > 4. In the auth/cred mode, it enables to cache the configuration file, >to avoid read and analyze it twice. > (Therefore, most of the part in the original one got replaced) > > The default configuration file is "/etc/security/capability.conf". > You can describe as follows: > > # kaigai get cap_net_raw and cap_kill, tak get cap_sys_pacct pI. > # We can omit "i:" in the head of each line. > i:cap_net_raw,cap_kill kaigai > cap_sys_pacct tak > > # ymj and tak lost cap_sys_chroot from cap_bset > b:cap_sys_chroot ymj tak > > # Any user within webadm group get cap_net_bind_service pI. > i:cap_net_bind_service @webadm > > # Any user within users group lost cap_sys_module from cap_bset > b:cap_sys_module @users > > > When a user or groups he belongs is on several lines, all configurations > are simplly compounded. > > In the above example, if tak belongs to webadm and users group, > he will get cap_sys_pacct and cap_net_bind_service pI, and lost > cap_sys_chroot and cap_sys_module from his cap_bset. > > Thanks, Signed-off-by: KaiGai Kohei <[EMAIL PROTECTED]> -- pam_cap/capability.conf |6 + pam_cap/pam_cap.c | 495 --- 2 files changed, 305 insertions(+), 196 deletions(-) diff --git a/pam_cap/capability.conf b/pam_cap/capability.conf index b543142..707cdc3 100644 --- a/pam_cap/capability.conf +++ b/pam_cap/capability.conf @@ -24,6 +24,12 @@ cap_setfcap morgan ## 'everyone else' gets no inheritable capabilities none * +# user 'kaigai' lost CAP_NET_RAW capability from bounding set +b:cap_net_raw kaigai + +# group 'acctadm' get CAP_SYS_PACCT inheritable capability +i:cap_sys_pacct @acctadm + ## if there is no '*' entry, all users not explicitly mentioned will ## get all available capabilities. This is a permissive default, and ## probably not what you want... diff --git a/pam_cap/pam_cap.c b/pam_cap/pam_cap.c index 94c5ebc..a917d5c 100644 --- a/pam_cap/pam_cap.c +++ b/pam_cap/pam_cap.c @@ -1,5 +1,6 @@ /* * Copyright (c) 1999,2007 Andrew G. Morgan <[EMAIL PROTECTED]> + * Copyright (c) 2007 KaiGai Kohei <[EMAIL PROTECTED]> * * The purpose of this module is to enforce inheritable capability sets * for a specified user. @@ -13,298 +14,400 @@ #include #include #include +#include +#include #include +#include #include #include +#define MODULE_NAME"pam_cap" #define USER_CAP_FILE "/etc/security/capability.conf" #define CAP_FILE_BUFFER_SIZE4096 #define CAP_FILE_DELIMITERS " \t\n" -#define CAP_COMBINED_FORMAT "%s all-i %s+i" -#define CAP_DROP_ALL"%s all-i" + +#ifndef PR_CAPBSET_DROP +#define PR_CAPBSET_DROP24 +#endif + +extern char const *_cap_names[]; struct pam_cap_s { int debug; const char *user; const char *conf_filename; +/* set in read_capabilities_for_user() */ +cap_t result; +int do_set_inh : 1; +int do_set_bset : 1; }; -/* obtain the inheritable capabilities for the current user */ - -static char *read_capabilities_for_user(const char *user, const char *source) +/* obtain the inheritable/bounding capabilities for the current user */ +static int read_capabilities_for_user(struct pam_cap_s *pcs) { -char *cap_string = NULL; -char buffer[CAP_FILE_BUFFER_SIZE], *line; +char buffer[CAP_FILE_BUFFER_SIZE]; FILE *cap_file; +struct passwd *pwd; +int line_num = 0; +int rc = -1; /* PAM_(AUTH|CRED|SESSION)_ERR */ + +pwd = getpwnam(pcs->user); +if (!pwd) { + syslog(LOG_ERR, "user %s not in passwd entries", pcs->user); + return PAM_AUTH_ERR; +} -cap_file = fopen(source, "r"); -if (cap_file == NULL) { - D(("failed to open capability file")); - return NULL; +cap_file = fopen(pcs->conf_filename, "r"); +if (!cap_file) { + if (errno == ENOENT) { + syslog(LOG_NOTICE, "%s is not found", + pcs->conf_filename); + return PAM_IGNORE; + } else { + syslog(LOG_ERR, "unable to open '%s' (%s)", + pcs->conf_filename, strerror(errno)); + return rc; + } } -while ((line = fgets(buffer, CAP_FILE_BUFFER_SIZE, cap_file))) { - int found_one = 0; - const char *cap_text; +pcs->result = NULL; +while
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: BTW, could you tell me your intention about pam_cap.c is implemented with pam_sm_authenticate() and pam_sm_setcred()? I think it can be done with pam_sm_open_session(), and this approach enables to reduce the iteration of reading /etc/security/capability.conf. How do you think the idea? Good question! If you want to add session support you can. I'd prefer it if you retained support for the auth/cred API too: admin choice and all that. To remove the second read of the file, you can use a PAM data item to cache the desired capability info after the first read of the file. I added session API support with retaining auth/cred API, and PAM data item caching feature using pam_(get|set)_data. It enables to kill the seconf read of the configuration file. Thanks for your suggestion. Followings are detailed explanation and the patch. I implemented it as a credential module (which has to get the authentication return code right to make the credential stack execute correctly) because I think of capabilities as credentials. That being said, the credentials vs. session thing is not well delineated by many applications, so it is arguably useful to provide both interfaces for the admin to make use of on a per application basis. The attached patch provides several improvement for pam_cap module. 1. It enables pam_cap to drop capabilities from process'es capability bounding set. 2. It enables to specify allowing inheritable capability set or dropping bounding capability set for groups, not only users. 3. It provide pam_sm_session() method, not only pam_sm_authenticate() and pam_sm_setcred(). A system administrator can select more appropriate mode for his purpose. 4. In the auth/cred mode, it enables to cache the configuration file, to avoid read and analyze it twice. (Therefore, most of the part in the original one got replaced) The default configuration file is "/etc/security/capability.conf". You can describe as follows: # kaigai get cap_net_raw and cap_kill, tak get cap_sys_pacct pI. # We can omit "i:" in the head of each line. i:cap_net_raw,cap_kill kaigai cap_sys_pacct tak # ymj and tak lost cap_sys_chroot from cap_bset b:cap_sys_chroot ymj tak # Any user within webadm group get cap_net_bind_service pI. i:cap_net_bind_service @webadm # Any user within users group lost cap_sys_module from cap_bset b:cap_sys_module @users When a user or groups he belongs is on several lines, all configurations are simplly compounded. In the above example, if tak belongs to webadm and users group, he will get cap_sys_pacct and cap_net_bind_service pI, and lost cap_sys_chroot and cap_sys_module from his cap_bset. Thanks, -- OSS Platform Development Division, NEC KaiGai Kohei <[EMAIL PROTECTED]> Signed-off-by: KaiGai Kohei <[EMAIL PROTECTED]> -- pam_cap/capability.conf |6 + pam_cap/pam_cap.c | 495 --- 2 files changed, 305 insertions(+), 196 deletions(-) diff --git a/pam_cap/capability.conf b/pam_cap/capability.conf index b543142..707cdc3 100644 --- a/pam_cap/capability.conf +++ b/pam_cap/capability.conf @@ -24,6 +24,12 @@ cap_setfcap morgan ## 'everyone else' gets no inheritable capabilities none * +# user 'kaigai' lost CAP_NET_RAW capability from bounding set +b:cap_net_raw kaigai + +# group 'acctadm' get CAP_SYS_PACCT inheritable capability +i:cap_sys_pacct @acctadm + ## if there is no '*' entry, all users not explicitly mentioned will ## get all available capabilities. This is a permissive default, and ## probably not what you want... diff --git a/pam_cap/pam_cap.c b/pam_cap/pam_cap.c index 94c5ebc..a917d5c 100644 --- a/pam_cap/pam_cap.c +++ b/pam_cap/pam_cap.c @@ -1,5 +1,6 @@ /* * Copyright (c) 1999,2007 Andrew G. Morgan <[EMAIL PROTECTED]> + * Copyright (c) 2007 KaiGai Kohei <[EMAIL PROTECTED]> * * The purpose of this module is to enforce inheritable capability sets * for a specified user. @@ -13,298 +14,400 @@ #include #include #include +#include +#include #include +#include #include #include +#define MODULE_NAME"pam_cap" #define USER_CAP_FILE "/etc/security/capability.conf" #define CAP_FILE_BUFFER_SIZE4096 #define CAP_FILE_DELIMITERS " \t\n" -#define CAP_COMBINED_FORMAT "%s all-i %s+i" -#define CAP_DROP_ALL"%s all-i" + +#ifndef PR_CAPBSET_DROP +#define PR_CAPBSET_DROP24 +#endif + +extern char const *_cap_names[]; struct pam_cap_s { int debug; const char *user; const char *conf_filename; +/* set in read_capabilities_for_user() */ +cap_t result; +int do_set_inh : 1; +int do_set_bset : 1; }; -/* obtain the inheritable capabilities for the current user */ - -static char
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: BTW, could you tell me your intention about pam_cap.c is implemented with pam_sm_authenticate() and pam_sm_setcred()? I think it can be done with pam_sm_open_session(), and this approach enables to reduce the iteration of reading /etc/security/capability.conf. How do you think the idea? Good question! If you want to add session support you can. I'd prefer it if you retained support for the auth/cred API too: admin choice and all that. To remove the second read of the file, you can use a PAM data item to cache the desired capability info after the first read of the file. I added session API support with retaining auth/cred API, and PAM data item caching feature using pam_(get|set)_data. It enables to kill the seconf read of the configuration file. Thanks for your suggestion. Followings are detailed explanation and the patch. I implemented it as a credential module (which has to get the authentication return code right to make the credential stack execute correctly) because I think of capabilities as credentials. That being said, the credentials vs. session thing is not well delineated by many applications, so it is arguably useful to provide both interfaces for the admin to make use of on a per application basis. The attached patch provides several improvement for pam_cap module. 1. It enables pam_cap to drop capabilities from process'es capability bounding set. 2. It enables to specify allowing inheritable capability set or dropping bounding capability set for groups, not only users. 3. It provide pam_sm_session() method, not only pam_sm_authenticate() and pam_sm_setcred(). A system administrator can select more appropriate mode for his purpose. 4. In the auth/cred mode, it enables to cache the configuration file, to avoid read and analyze it twice. (Therefore, most of the part in the original one got replaced) The default configuration file is /etc/security/capability.conf. You can describe as follows: # kaigai get cap_net_raw and cap_kill, tak get cap_sys_pacct pI. # We can omit i: in the head of each line. i:cap_net_raw,cap_kill kaigai cap_sys_pacct tak # ymj and tak lost cap_sys_chroot from cap_bset b:cap_sys_chroot ymj tak # Any user within webadm group get cap_net_bind_service pI. i:cap_net_bind_service @webadm # Any user within users group lost cap_sys_module from cap_bset b:cap_sys_module @users When a user or groups he belongs is on several lines, all configurations are simplly compounded. In the above example, if tak belongs to webadm and users group, he will get cap_sys_pacct and cap_net_bind_service pI, and lost cap_sys_chroot and cap_sys_module from his cap_bset. Thanks, -- OSS Platform Development Division, NEC KaiGai Kohei [EMAIL PROTECTED] Signed-off-by: KaiGai Kohei [EMAIL PROTECTED] -- pam_cap/capability.conf |6 + pam_cap/pam_cap.c | 495 --- 2 files changed, 305 insertions(+), 196 deletions(-) diff --git a/pam_cap/capability.conf b/pam_cap/capability.conf index b543142..707cdc3 100644 --- a/pam_cap/capability.conf +++ b/pam_cap/capability.conf @@ -24,6 +24,12 @@ cap_setfcap morgan ## 'everyone else' gets no inheritable capabilities none * +# user 'kaigai' lost CAP_NET_RAW capability from bounding set +b:cap_net_raw kaigai + +# group 'acctadm' get CAP_SYS_PACCT inheritable capability +i:cap_sys_pacct @acctadm + ## if there is no '*' entry, all users not explicitly mentioned will ## get all available capabilities. This is a permissive default, and ## probably not what you want... diff --git a/pam_cap/pam_cap.c b/pam_cap/pam_cap.c index 94c5ebc..a917d5c 100644 --- a/pam_cap/pam_cap.c +++ b/pam_cap/pam_cap.c @@ -1,5 +1,6 @@ /* * Copyright (c) 1999,2007 Andrew G. Morgan [EMAIL PROTECTED] + * Copyright (c) 2007 KaiGai Kohei [EMAIL PROTECTED] * * The purpose of this module is to enforce inheritable capability sets * for a specified user. @@ -13,298 +14,400 @@ #include stdarg.h #include stdlib.h #include syslog.h +#include pwd.h +#include grp.h #include sys/capability.h +#include sys/prctl.h #include security/pam_modules.h #include security/_pam_macros.h +#define MODULE_NAMEpam_cap #define USER_CAP_FILE /etc/security/capability.conf #define CAP_FILE_BUFFER_SIZE4096 #define CAP_FILE_DELIMITERS \t\n -#define CAP_COMBINED_FORMAT %s all-i %s+i -#define CAP_DROP_ALL%s all-i + +#ifndef PR_CAPBSET_DROP +#define PR_CAPBSET_DROP24 +#endif + +extern char const *_cap_names[]; struct pam_cap_s { int debug; const char *user; const char *conf_filename; +/* set in read_capabilities_for_user() */ +cap_t result; +int do_set_inh : 1; +int do_set_bset : 1; }; -/* obtain the
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Sorry, any TABs are replaced by MUA. I'll send the patch again. The attached patch provides several improvement for pam_cap module. 1. It enables pam_cap to drop capabilities from process'es capability bounding set. 2. It enables to specify allowing inheritable capability set or dropping bounding capability set for groups, not only users. 3. It provide pam_sm_session() method, not only pam_sm_authenticate() and pam_sm_setcred(). A system administrator can select more appropriate mode for his purpose. 4. In the auth/cred mode, it enables to cache the configuration file, to avoid read and analyze it twice. (Therefore, most of the part in the original one got replaced) The default configuration file is /etc/security/capability.conf. You can describe as follows: # kaigai get cap_net_raw and cap_kill, tak get cap_sys_pacct pI. # We can omit i: in the head of each line. i:cap_net_raw,cap_kill kaigai cap_sys_pacct tak # ymj and tak lost cap_sys_chroot from cap_bset b:cap_sys_chroot ymj tak # Any user within webadm group get cap_net_bind_service pI. i:cap_net_bind_service @webadm # Any user within users group lost cap_sys_module from cap_bset b:cap_sys_module @users When a user or groups he belongs is on several lines, all configurations are simplly compounded. In the above example, if tak belongs to webadm and users group, he will get cap_sys_pacct and cap_net_bind_service pI, and lost cap_sys_chroot and cap_sys_module from his cap_bset. Thanks, Signed-off-by: KaiGai Kohei [EMAIL PROTECTED] -- pam_cap/capability.conf |6 + pam_cap/pam_cap.c | 495 --- 2 files changed, 305 insertions(+), 196 deletions(-) diff --git a/pam_cap/capability.conf b/pam_cap/capability.conf index b543142..707cdc3 100644 --- a/pam_cap/capability.conf +++ b/pam_cap/capability.conf @@ -24,6 +24,12 @@ cap_setfcap morgan ## 'everyone else' gets no inheritable capabilities none * +# user 'kaigai' lost CAP_NET_RAW capability from bounding set +b:cap_net_raw kaigai + +# group 'acctadm' get CAP_SYS_PACCT inheritable capability +i:cap_sys_pacct @acctadm + ## if there is no '*' entry, all users not explicitly mentioned will ## get all available capabilities. This is a permissive default, and ## probably not what you want... diff --git a/pam_cap/pam_cap.c b/pam_cap/pam_cap.c index 94c5ebc..a917d5c 100644 --- a/pam_cap/pam_cap.c +++ b/pam_cap/pam_cap.c @@ -1,5 +1,6 @@ /* * Copyright (c) 1999,2007 Andrew G. Morgan [EMAIL PROTECTED] + * Copyright (c) 2007 KaiGai Kohei [EMAIL PROTECTED] * * The purpose of this module is to enforce inheritable capability sets * for a specified user. @@ -13,298 +14,400 @@ #include stdarg.h #include stdlib.h #include syslog.h +#include pwd.h +#include grp.h #include sys/capability.h +#include sys/prctl.h #include security/pam_modules.h #include security/_pam_macros.h +#define MODULE_NAMEpam_cap #define USER_CAP_FILE /etc/security/capability.conf #define CAP_FILE_BUFFER_SIZE4096 #define CAP_FILE_DELIMITERS \t\n -#define CAP_COMBINED_FORMAT %s all-i %s+i -#define CAP_DROP_ALL%s all-i + +#ifndef PR_CAPBSET_DROP +#define PR_CAPBSET_DROP24 +#endif + +extern char const *_cap_names[]; struct pam_cap_s { int debug; const char *user; const char *conf_filename; +/* set in read_capabilities_for_user() */ +cap_t result; +int do_set_inh : 1; +int do_set_bset : 1; }; -/* obtain the inheritable capabilities for the current user */ - -static char *read_capabilities_for_user(const char *user, const char *source) +/* obtain the inheritable/bounding capabilities for the current user */ +static int read_capabilities_for_user(struct pam_cap_s *pcs) { -char *cap_string = NULL; -char buffer[CAP_FILE_BUFFER_SIZE], *line; +char buffer[CAP_FILE_BUFFER_SIZE]; FILE *cap_file; +struct passwd *pwd; +int line_num = 0; +int rc = -1; /* PAM_(AUTH|CRED|SESSION)_ERR */ + +pwd = getpwnam(pcs-user); +if (!pwd) { + syslog(LOG_ERR, user %s not in passwd entries, pcs-user); + return PAM_AUTH_ERR; +} -cap_file = fopen(source, r); -if (cap_file == NULL) { - D((failed to open capability file)); - return NULL; +cap_file = fopen(pcs-conf_filename, r); +if (!cap_file) { + if (errno == ENOENT) { + syslog(LOG_NOTICE, %s is not found, + pcs-conf_filename); + return PAM_IGNORE; + } else { + syslog(LOG_ERR, unable to open '%s' (%s), + pcs-conf_filename, strerror(errno)); + return rc; + } } -while ((line = fgets(buffer, CAP_FILE_BUFFER_SIZE, cap_file))) { - int found_one = 0; - const char *cap_text; +
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 I've pushed it to a pamcap-enhancements branch and I'll will try to review it quickly. Thanks Andrew KaiGai Kohei wrote: Sorry, any TABs are replaced by MUA. I'll send the patch again. The attached patch provides several improvement for pam_cap module. 1. It enables pam_cap to drop capabilities from process'es capability bounding set. 2. It enables to specify allowing inheritable capability set or dropping bounding capability set for groups, not only users. 3. It provide pam_sm_session() method, not only pam_sm_authenticate() and pam_sm_setcred(). A system administrator can select more appropriate mode for his purpose. 4. In the auth/cred mode, it enables to cache the configuration file, to avoid read and analyze it twice. (Therefore, most of the part in the original one got replaced) The default configuration file is /etc/security/capability.conf. You can describe as follows: # kaigai get cap_net_raw and cap_kill, tak get cap_sys_pacct pI. # We can omit i: in the head of each line. i:cap_net_raw,cap_kill kaigai cap_sys_pacct tak # ymj and tak lost cap_sys_chroot from cap_bset b:cap_sys_chroot ymj tak # Any user within webadm group get cap_net_bind_service pI. i:cap_net_bind_service @webadm # Any user within users group lost cap_sys_module from cap_bset b:cap_sys_module @users When a user or groups he belongs is on several lines, all configurations are simplly compounded. In the above example, if tak belongs to webadm and users group, he will get cap_sys_pacct and cap_net_bind_service pI, and lost cap_sys_chroot and cap_sys_module from his cap_bset. Thanks, Signed-off-by: KaiGai Kohei [EMAIL PROTECTED] -- pam_cap/capability.conf |6 + pam_cap/pam_cap.c | 495 --- 2 files changed, 305 insertions(+), 196 deletions(-) diff --git a/pam_cap/capability.conf b/pam_cap/capability.conf index b543142..707cdc3 100644 --- a/pam_cap/capability.conf +++ b/pam_cap/capability.conf @@ -24,6 +24,12 @@ cap_setfcapmorgan ## 'everyone else' gets no inheritable capabilities none * +# user 'kaigai' lost CAP_NET_RAW capability from bounding set +b:cap_net_raw kaigai + +# group 'acctadm' get CAP_SYS_PACCT inheritable capability +i:cap_sys_pacct @acctadm + ## if there is no '*' entry, all users not explicitly mentioned will ## get all available capabilities. This is a permissive default, and ## probably not what you want... diff --git a/pam_cap/pam_cap.c b/pam_cap/pam_cap.c index 94c5ebc..a917d5c 100644 --- a/pam_cap/pam_cap.c +++ b/pam_cap/pam_cap.c @@ -1,5 +1,6 @@ /* * Copyright (c) 1999,2007 Andrew G. Morgan [EMAIL PROTECTED] + * Copyright (c) 2007 KaiGai Kohei [EMAIL PROTECTED] * * The purpose of this module is to enforce inheritable capability sets * for a specified user. @@ -13,298 +14,400 @@ #include stdarg.h #include stdlib.h #include syslog.h +#include pwd.h +#include grp.h #include sys/capability.h +#include sys/prctl.h #include security/pam_modules.h #include security/_pam_macros.h +#define MODULE_NAME pam_cap #define USER_CAP_FILE /etc/security/capability.conf #define CAP_FILE_BUFFER_SIZE4096 #define CAP_FILE_DELIMITERS \t\n -#define CAP_COMBINED_FORMAT %s all-i %s+i -#define CAP_DROP_ALL%s all-i + +#ifndef PR_CAPBSET_DROP +#define PR_CAPBSET_DROP 24 +#endif + +extern char const *_cap_names[]; struct pam_cap_s { int debug; const char *user; const char *conf_filename; +/* set in read_capabilities_for_user() */ +cap_t result; +int do_set_inh : 1; +int do_set_bset : 1; }; -/* obtain the inheritable capabilities for the current user */ - -static char *read_capabilities_for_user(const char *user, const char *source) +/* obtain the inheritable/bounding capabilities for the current user */ +static int read_capabilities_for_user(struct pam_cap_s *pcs) { -char *cap_string = NULL; -char buffer[CAP_FILE_BUFFER_SIZE], *line; +char buffer[CAP_FILE_BUFFER_SIZE]; FILE *cap_file; +struct passwd *pwd; +int line_num = 0; +int rc = -1; /* PAM_(AUTH|CRED|SESSION)_ERR */ + +pwd = getpwnam(pcs-user); +if (!pwd) { + syslog(LOG_ERR, user %s not in passwd entries, pcs-user); + return PAM_AUTH_ERR; +} -cap_file = fopen(source, r); -if (cap_file == NULL) { - D((failed to open capability file)); - return NULL; +cap_file = fopen(pcs-conf_filename, r); +if (!cap_file) { + if (errno == ENOENT) { + syslog(LOG_NOTICE, %s is not found, +pcs-conf_filename); + return PAM_IGNORE; + } else { + syslog(LOG_ERR,
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: > BTW, could you tell me your intention about pam_cap.c is implemented > with pam_sm_authenticate() and pam_sm_setcred()? > I think it can be done with pam_sm_open_session(), and this approach > enables to reduce the iteration of reading /etc/security/capability.conf. > > How do you think the idea? Good question! If you want to add session support you can. I'd prefer it if you retained support for the auth/cred API too: admin choice and all that. To remove the second read of the file, you can use a PAM data item to cache the desired capability info after the first read of the file. I implemented it as a credential module (which has to get the authentication return code right to make the credential stack execute correctly) because I think of capabilities as credentials. That being said, the credentials vs. session thing is not well delineated by many applications, so it is arguably useful to provide both interfaces for the admin to make use of on a per application basis. Cheers Andrew -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHV4r8mwytjiwfWMwRAlOsAJ9MQQN0cLhH2lhx9gwvwHsMhQ72ggCfcKWt /krnNdiAisfcbcXDfssdbLE= =+0r1 -END PGP SIGNATURE- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: +if (!!cap_issubset(*inheritable, + cap_combine(target->cap_inheritable, + current->cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} Yes, the !! was a bug. The correct check is a single !. I was in trouble with getting -EPERM at pam_cap.so :-) (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) If this condition intends to dominate 'new' pI bits by 'old' pI bits masked with bounding set, we should not apply cap_combine() here. I think applying cap_intersect() is correct for the purpose. The check is not meant to limit existing pI bits. The check is meant to limit what new bits can be 'added' to pI (in the case that pE & CAP_SETPCAP is true). Thanks, I got understood as I wrote in the previous reply. BTW, could you tell me your intention about pam_cap.c is implemented with pam_sm_authenticate() and pam_sm_setcred()? I think it can be done with pam_sm_open_session(), and this approach enables to reduce the iteration of reading /etc/security/capability.conf. How do you think the idea? -- OSS Platform Development Division, NEC KaiGai Kohei <[EMAIL PROTECTED]> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
(Thus, the correct check says no 'new' pI bits can be outside cap_bset.) If this condition intends to dominate 'new' pI bits by 'old' pI bits masked with bounding set, we should not apply cap_combine() here. I think applying cap_intersect() is correct for the purpose. That would have been my first inclination, but Andrew actually wanted to be able to keep a pI with bits not in the capability bounding set. And it's really not a big problem, since 1. you can never grow cap_bset 2. the capbound.c program just makes sure to call capset to take the bit being removed from cap_bset out of pI' 3. It could be advantageous for some daemon to keep a bit in pI which can never be gained through fP but can be gained by a child through (fI). Does that seem reasonable to you? OK, I got understood the intention of the condition. It seems to me reasonable policy. Thanks, -- OSS Platform Development Division, NEC KaiGai Kohei <[EMAIL PROTECTED]> This patch fixes incorrect condition added by per-process capability bounding set patch. It intends to limit no new pI capabilities outside bounding set. Signed-off-by: KaiGai Kohei <[EMAIL PROTECTED]> commoncap.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) --- linux-2.6.24-rc3/security/commoncap.c.old 2007-12-06 10:51:48.0 +0900 +++ linux-2.6.24-rc3/security/commoncap.c 2007-12-06 10:52:15.0 +0900 @@ -119,9 +119,9 @@ int cap_capset_check (struct task_struct /* incapable of using this inheritable set */ return -EPERM; } - if (!!cap_issubset(*inheritable, - cap_combine(target->cap_inheritable, - current->cap_bset))) { + if (!cap_issubset(*inheritable, + cap_combine(target->cap_inheritable, + current->cap_bset))) { /* no new pI capabilities outside bounding set */ return -EPERM; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: > Andrew Morgan wrote: >> -BEGIN PGP SIGNED MESSAGE- >> Hash: SHA1 >> >> KaiGai Kohei wrote: +if (!!cap_issubset(*inheritable, + cap_combine(target->cap_inheritable, + current->cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} >> Yes, the !! was a bug. The correct check is a single !. > > I was in trouble with getting -EPERM at pam_cap.so :-) > >> (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) > > If this condition intends to dominate 'new' pI bits by 'old' pI bits masked > with bounding set, we should not apply cap_combine() here. > I think applying cap_intersect() is correct for the purpose. The check is not meant to limit existing pI bits. The check is meant to limit what new bits can be 'added' to pI (in the case that pE & CAP_SETPCAP is true). Cheers Andrew -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHVsQ2mwytjiwfWMwRAs9RAKCUyjsjONVhRXooG5I2b+1zU/HLGwCfQIyh tjdDI9QxJ1DWLCm2Ee29qYA= =Gwwt -END PGP SIGNATURE- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: +if (!!cap_issubset(*inheritable, + cap_combine(target-cap_inheritable, + current-cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} Yes, the !! was a bug. The correct check is a single !. I was in trouble with getting -EPERM at pam_cap.so :-) (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) If this condition intends to dominate 'new' pI bits by 'old' pI bits masked with bounding set, we should not apply cap_combine() here. I think applying cap_intersect() is correct for the purpose. The check is not meant to limit existing pI bits. The check is meant to limit what new bits can be 'added' to pI (in the case that pE CAP_SETPCAP is true). Cheers Andrew -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHVsQ2mwytjiwfWMwRAs9RAKCUyjsjONVhRXooG5I2b+1zU/HLGwCfQIyh tjdDI9QxJ1DWLCm2Ee29qYA= =Gwwt -END PGP SIGNATURE- -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
(Thus, the correct check says no 'new' pI bits can be outside cap_bset.) If this condition intends to dominate 'new' pI bits by 'old' pI bits masked with bounding set, we should not apply cap_combine() here. I think applying cap_intersect() is correct for the purpose. That would have been my first inclination, but Andrew actually wanted to be able to keep a pI with bits not in the capability bounding set. And it's really not a big problem, since 1. you can never grow cap_bset 2. the capbound.c program just makes sure to call capset to take the bit being removed from cap_bset out of pI' 3. It could be advantageous for some daemon to keep a bit in pI which can never be gained through fP but can be gained by a child through (fIpI). Does that seem reasonable to you? OK, I got understood the intention of the condition. It seems to me reasonable policy. Thanks, -- OSS Platform Development Division, NEC KaiGai Kohei [EMAIL PROTECTED] This patch fixes incorrect condition added by per-process capability bounding set patch. It intends to limit no new pI capabilities outside bounding set. Signed-off-by: KaiGai Kohei [EMAIL PROTECTED] commoncap.c |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) --- linux-2.6.24-rc3/security/commoncap.c.old 2007-12-06 10:51:48.0 +0900 +++ linux-2.6.24-rc3/security/commoncap.c 2007-12-06 10:52:15.0 +0900 @@ -119,9 +119,9 @@ int cap_capset_check (struct task_struct /* incapable of using this inheritable set */ return -EPERM; } - if (!!cap_issubset(*inheritable, - cap_combine(target-cap_inheritable, - current-cap_bset))) { + if (!cap_issubset(*inheritable, + cap_combine(target-cap_inheritable, + current-cap_bset))) { /* no new pI capabilities outside bounding set */ return -EPERM; } -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: +if (!!cap_issubset(*inheritable, + cap_combine(target-cap_inheritable, + current-cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} Yes, the !! was a bug. The correct check is a single !. I was in trouble with getting -EPERM at pam_cap.so :-) (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) If this condition intends to dominate 'new' pI bits by 'old' pI bits masked with bounding set, we should not apply cap_combine() here. I think applying cap_intersect() is correct for the purpose. The check is not meant to limit existing pI bits. The check is meant to limit what new bits can be 'added' to pI (in the case that pE CAP_SETPCAP is true). Thanks, I got understood as I wrote in the previous reply. BTW, could you tell me your intention about pam_cap.c is implemented with pam_sm_authenticate() and pam_sm_setcred()? I think it can be done with pam_sm_open_session(), and this approach enables to reduce the iteration of reading /etc/security/capability.conf. How do you think the idea? -- OSS Platform Development Division, NEC KaiGai Kohei [EMAIL PROTECTED] -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: BTW, could you tell me your intention about pam_cap.c is implemented with pam_sm_authenticate() and pam_sm_setcred()? I think it can be done with pam_sm_open_session(), and this approach enables to reduce the iteration of reading /etc/security/capability.conf. How do you think the idea? Good question! If you want to add session support you can. I'd prefer it if you retained support for the auth/cred API too: admin choice and all that. To remove the second read of the file, you can use a PAM data item to cache the desired capability info after the first read of the file. I implemented it as a credential module (which has to get the authentication return code right to make the credential stack execute correctly) because I think of capabilities as credentials. That being said, the credentials vs. session thing is not well delineated by many applications, so it is arguably useful to provide both interfaces for the admin to make use of on a per application basis. Cheers Andrew -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHV4r8mwytjiwfWMwRAlOsAJ9MQQN0cLhH2lhx9gwvwHsMhQ72ggCfcKWt /krnNdiAisfcbcXDfssdbLE= =+0r1 -END PGP SIGNATURE- -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Quoting KaiGai Kohei ([EMAIL PROTECTED]): > Andrew Morgan wrote: >> -BEGIN PGP SIGNED MESSAGE- >> Hash: SHA1 >> KaiGai Kohei wrote: >>> Serge, >>> >>> Please tell me the meanings of the following condition. >>> diff --git a/security/commoncap.c b/security/commoncap.c index 3a95990..cb71bb0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -133,6 +119,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, /* incapable of using this inheritable set */ return -EPERM; } +if (!!cap_issubset(*inheritable, + cap_combine(target->cap_inheritable, + current->cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} /* verify restrictions on target's new Permitted set */ if (!cap_issubset (*permitted, >>> It seems to me this condition requires the new inheritable capability >>> set must have a capability more than bounding set, at least. >>> What is the purpose of this checking? >> Yes, the !! was a bug. The correct check is a single !. > > I was in trouble with getting -EPERM at pam_cap.so :-) > >> (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) > > If this condition intends to dominate 'new' pI bits by 'old' pI bits masked > with bounding set, we should not apply cap_combine() here. > I think applying cap_intersect() is correct for the purpose. That would have been my first inclination, but Andrew actually wanted to be able to keep a pI with bits not in the capability bounding set. And it's really not a big problem, since 1. you can never grow cap_bset 2. the capbound.c program just makes sure to call capset to take the bit being removed from cap_bset out of pI' 3. It could be advantageous for some daemon to keep a bit in pI which can never be gained through fP but can be gained by a child through (fI). Does that seem reasonable to you? (On the one hand man 7 capabilities shows cap_bset affecting fP and not pP', on the other hand we're definately getting into the territory where we'll have to rewrite the manpages anyway) thanks, -serge -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: Serge, Please tell me the meanings of the following condition. diff --git a/security/commoncap.c b/security/commoncap.c index 3a95990..cb71bb0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -133,6 +119,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, /* incapable of using this inheritable set */ return -EPERM; } +if (!!cap_issubset(*inheritable, + cap_combine(target->cap_inheritable, + current->cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} /* verify restrictions on target's new Permitted set */ if (!cap_issubset (*permitted, It seems to me this condition requires the new inheritable capability set must have a capability more than bounding set, at least. What is the purpose of this checking? Yes, the !! was a bug. The correct check is a single !. I was in trouble with getting -EPERM at pam_cap.so :-) (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) If this condition intends to dominate 'new' pI bits by 'old' pI bits masked with bounding set, we should not apply cap_combine() here. I think applying cap_intersect() is correct for the purpose. Thanks, -- KaiGai Kohei -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: Serge, Please tell me the meanings of the following condition. diff --git a/security/commoncap.c b/security/commoncap.c index 3a95990..cb71bb0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -133,6 +119,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, /* incapable of using this inheritable set */ return -EPERM; } +if (!!cap_issubset(*inheritable, + cap_combine(target-cap_inheritable, + current-cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} /* verify restrictions on target's new Permitted set */ if (!cap_issubset (*permitted, It seems to me this condition requires the new inheritable capability set must have a capability more than bounding set, at least. What is the purpose of this checking? Yes, the !! was a bug. The correct check is a single !. I was in trouble with getting -EPERM at pam_cap.so :-) (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) If this condition intends to dominate 'new' pI bits by 'old' pI bits masked with bounding set, we should not apply cap_combine() here. I think applying cap_intersect() is correct for the purpose. Thanks, -- KaiGai Kohei -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Quoting KaiGai Kohei ([EMAIL PROTECTED]): Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: Serge, Please tell me the meanings of the following condition. diff --git a/security/commoncap.c b/security/commoncap.c index 3a95990..cb71bb0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -133,6 +119,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, /* incapable of using this inheritable set */ return -EPERM; } +if (!!cap_issubset(*inheritable, + cap_combine(target-cap_inheritable, + current-cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} /* verify restrictions on target's new Permitted set */ if (!cap_issubset (*permitted, It seems to me this condition requires the new inheritable capability set must have a capability more than bounding set, at least. What is the purpose of this checking? Yes, the !! was a bug. The correct check is a single !. I was in trouble with getting -EPERM at pam_cap.so :-) (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) If this condition intends to dominate 'new' pI bits by 'old' pI bits masked with bounding set, we should not apply cap_combine() here. I think applying cap_intersect() is correct for the purpose. That would have been my first inclination, but Andrew actually wanted to be able to keep a pI with bits not in the capability bounding set. And it's really not a big problem, since 1. you can never grow cap_bset 2. the capbound.c program just makes sure to call capset to take the bit being removed from cap_bset out of pI' 3. It could be advantageous for some daemon to keep a bit in pI which can never be gained through fP but can be gained by a child through (fIpI). Does that seem reasonable to you? (On the one hand man 7 capabilities shows cap_bset affecting fP and not pP', on the other hand we're definately getting into the territory where we'll have to rewrite the manpages anyway) thanks, -serge -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: > Serge, > > Please tell me the meanings of the following condition. > >> diff --git a/security/commoncap.c b/security/commoncap.c >> index 3a95990..cb71bb0 100644 >> --- a/security/commoncap.c >> +++ b/security/commoncap.c >> @@ -133,6 +119,12 @@ int cap_capset_check (struct task_struct *target, >> kernel_cap_t *effective, >> /* incapable of using this inheritable set */ >> return -EPERM; >> } >> +if (!!cap_issubset(*inheritable, >> + cap_combine(target->cap_inheritable, >> + current->cap_bset))) { >> +/* no new pI capabilities outside bounding set */ >> +return -EPERM; >> +} >> >> /* verify restrictions on target's new Permitted set */ >> if (!cap_issubset (*permitted, > > It seems to me this condition requires the new inheritable capability > set must have a capability more than bounding set, at least. > What is the purpose of this checking? Yes, the !! was a bug. The correct check is a single !. (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) Cheers Andrew > > In the initial state, any process have no inheritable capability set > and full bounding set. Thus, we cannot do capset() always. > > Thanks, -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHVPBS+bHCR3gb8jsRAnxQAJ0Vna82bl9M11OL/uuEe21nF5+9TACfSzGi aY0SUvMmLZCIF0KovBTpihE= =wT9N -END PGP SIGNATURE- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Serge, Please tell me the meanings of the following condition. diff --git a/security/commoncap.c b/security/commoncap.c index 3a95990..cb71bb0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -133,6 +119,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, /* incapable of using this inheritable set */ return -EPERM; } + if (!!cap_issubset(*inheritable, + cap_combine(target->cap_inheritable, + current->cap_bset))) { + /* no new pI capabilities outside bounding set */ + return -EPERM; + } /* verify restrictions on target's new Permitted set */ if (!cap_issubset (*permitted, It seems to me this condition requires the new inheritable capability set must have a capability more than bounding set, at least. What is the purpose of this checking? In the initial state, any process have no inheritable capability set and full bounding set. Thus, we cannot do capset() always. Thanks, -- OSS Platform Development Division, NEC KaiGai Kohei <[EMAIL PROTECTED]> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Serge, Please tell me the meanings of the following condition. diff --git a/security/commoncap.c b/security/commoncap.c index 3a95990..cb71bb0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -133,6 +119,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, /* incapable of using this inheritable set */ return -EPERM; } + if (!!cap_issubset(*inheritable, + cap_combine(target-cap_inheritable, + current-cap_bset))) { + /* no new pI capabilities outside bounding set */ + return -EPERM; + } /* verify restrictions on target's new Permitted set */ if (!cap_issubset (*permitted, It seems to me this condition requires the new inheritable capability set must have a capability more than bounding set, at least. What is the purpose of this checking? In the initial state, any process have no inheritable capability set and full bounding set. Thus, we cannot do capset() always. Thanks, -- OSS Platform Development Division, NEC KaiGai Kohei [EMAIL PROTECTED] -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: Serge, Please tell me the meanings of the following condition. diff --git a/security/commoncap.c b/security/commoncap.c index 3a95990..cb71bb0 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -133,6 +119,12 @@ int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, /* incapable of using this inheritable set */ return -EPERM; } +if (!!cap_issubset(*inheritable, + cap_combine(target-cap_inheritable, + current-cap_bset))) { +/* no new pI capabilities outside bounding set */ +return -EPERM; +} /* verify restrictions on target's new Permitted set */ if (!cap_issubset (*permitted, It seems to me this condition requires the new inheritable capability set must have a capability more than bounding set, at least. What is the purpose of this checking? Yes, the !! was a bug. The correct check is a single !. (Thus, the correct check says no 'new' pI bits can be outside cap_bset.) Cheers Andrew In the initial state, any process have no inheritable capability set and full bounding set. Thus, we cannot do capset() always. Thanks, -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.7 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFHVPBS+bHCR3gb8jsRAnxQAJ0Vna82bl9M11OL/uuEe21nF5+9TACfSzGi aY0SUvMmLZCIF0KovBTpihE= =wT9N -END PGP SIGNATURE- -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: There is already a pam_cap module in the libcap2 package. Can we merge this functionality? I think it is a good idea. However, this module already have a feature to modify inheritable capability set. How does it to be described in the "/etc/security/capability.conf"? One idea is like a following convention: # compatible configuration. We can omit "i:" at the head of line cap_setfcap tak # It drops any capabilities from b-set except for cap_net_raw and cap_fowner b:cap_net_raw,cap_fownerymj # It drops only cap_dac_override from b-set. b:-cap_dac_override kaigai # It drops only cap_sys_admin from b-set of any user within users group. b:-cap_sys_admingroup:users I like the idea of a separate line for bounds. For ease of parsing, perhaps '!' or some other symbol prefix to the line could be used to identify lines that refer to cap_bound? In other modules, @groupname is used to capture a group association. Lines like this should be supported: !cap_net_raw @regularusers# suppress from cap_bset cap_net_raw @pingers morgan # add to pI where morgan is not in group @pingers but is in group @regularusers. The "@groupname" is intuitive convention. I also think it is good idea. But !cap_xxx is a bit misunderstandable for me. Someone may misunderstand this line means any capabilities except for cap_xxx. Thus, I think that using "b:" and omittable "i:" prefix is better than "!". In addition, what is your opinion about using "-b:" and "-i:" to represent dropping capabilities currently they have? There is one more uncertain case. When a user belongs to several groups with capabilities configuration, what capabilities are to be attached for the user? e.g) When kaigai belong to @pingers and @paccters b:cap_sys_pacct @paccters b:cap_net_raw @pingers -b:cap_dac_override,cap_net_raw kaigai If we apply "OR" policy, kaigai get only cap_sys_pacct, because he got cap_sys_pacct and cap_net_raw came from @paccters and @pingers but cap_dac_override and cap_net_raw are dropped by the third line. Thanks, Cheers Andrew Thanks, Cheers Andrew [EMAIL PROTECTED] wrote: Quoting KaiGai Kohei ([EMAIL PROTECTED]): Serge E. Hallyn wrote: The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# Neat. A bigger-stick version of not adding the account to group wheel. I'll use that. Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. Thanks! I don't know what happened to my alias for him... thanks, -serge -- KaiGai Kohei <[EMAIL PROTECTED]> pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei <[EMAIL PROTECTED]> */ #include #include #include #include
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: >> There is already a pam_cap module in the libcap2 package. Can we merge >> this functionality? > > I think it is a good idea. > > However, this module already have a feature to modify inheritable > capability set. > How does it to be described in the "/etc/security/capability.conf"? > > One idea is like a following convention: > > # compatible configuration. We can omit "i:" at the head of line > cap_setfcap tak > # It drops any capabilities from b-set except for cap_net_raw and > cap_fowner > b:cap_net_raw,cap_fownerymj > # It drops only cap_dac_override from b-set. > b:-cap_dac_override kaigai > # It drops only cap_sys_admin from b-set of any user within users group. > b:-cap_sys_admingroup:users I like the idea of a separate line for bounds. For ease of parsing, perhaps '!' or some other symbol prefix to the line could be used to identify lines that refer to cap_bound? In other modules, @groupname is used to capture a group association. Lines like this should be supported: !cap_net_raw @regularusers# suppress from cap_bset cap_net_raw @pingers morgan # add to pI where morgan is not in group @pingers but is in group @regularusers. Cheers Andrew > > Thanks, > >> Cheers >> >> Andrew >> >> [EMAIL PROTECTED] wrote: >>> Quoting KaiGai Kohei ([EMAIL PROTECTED]): Serge E. Hallyn wrote: > The capability bounding set is a set beyond which capabilities > cannot grow. Currently cap_bset is per-system. It can be > manipulated through sysctl, but only init can add capabilities. > Root can remove capabilities. By default it includes all caps > except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# >>> Neat. A bigger-stick version of not adding the account to >>> group wheel. I'll use that. >>> >>> Is there any reason not to have a separate /etc/login.capbounds >>> config file, though, so the account can still have a full name? >>> Did you only use that for convenience of proof of concept, or >>> is there another reason? >>> # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. >>> Thanks! I don't know what happened to my alias for him... >>> >>> thanks, >>> -serge >>> -- KaiGai Kohei <[EMAIL PROTECTED]> pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei <[EMAIL PROTECTED]> */ #include #include #include #include #include #include #include #include #include #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif static char *captable[] = { "cap_chown", "cap_dac_override", "cap_dac_read_search", "cap_fowner", "cap_fsetid", "cap_kill", "cap_setgid", "cap_setuid", "cap_setpcap", "cap_linux_immutable", "cap_net_bind_service",
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: There is already a pam_cap module in the libcap2 package. Can we merge this functionality? I think it is a good idea. However, this module already have a feature to modify inheritable capability set. How does it to be described in the /etc/security/capability.conf? One idea is like a following convention: # compatible configuration. We can omit i: at the head of line cap_setfcap tak # It drops any capabilities from b-set except for cap_net_raw and cap_fowner b:cap_net_raw,cap_fownerymj # It drops only cap_dac_override from b-set. b:-cap_dac_override kaigai # It drops only cap_sys_admin from b-set of any user within users group. b:-cap_sys_admingroup:users I like the idea of a separate line for bounds. For ease of parsing, perhaps '!' or some other symbol prefix to the line could be used to identify lines that refer to cap_bound? In other modules, @groupname is used to capture a group association. Lines like this should be supported: !cap_net_raw @regularusers# suppress from cap_bset cap_net_raw @pingers morgan # add to pI where morgan is not in group @pingers but is in group @regularusers. Cheers Andrew Thanks, Cheers Andrew [EMAIL PROTECTED] wrote: Quoting KaiGai Kohei ([EMAIL PROTECTED]): Serge E. Hallyn wrote: The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# Neat. A bigger-stick version of not adding the account to group wheel. I'll use that. Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. Thanks! I don't know what happened to my alias for him... thanks, -serge -- KaiGai Kohei [EMAIL PROTECTED] pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei [EMAIL PROTECTED] */ #include errno.h #include pwd.h #include stdlib.h #include stdio.h #include string.h #include syslog.h #include sys/prctl.h #include sys/types.h #include security/pam_modules.h #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif static char *captable[] = { cap_chown, cap_dac_override, cap_dac_read_search, cap_fowner, cap_fsetid, cap_kill, cap_setgid, cap_setuid, cap_setpcap, cap_linux_immutable, cap_net_bind_service, cap_net_broadcast, cap_net_admin, cap_net_raw, cap_ipc_lock, cap_ipc_owner, cap_sys_module, cap_sys_rawio, cap_sys_chroot, cap_sys_ptrace, cap_sys_pacct, cap_sys_admin, cap_sys_boot, cap_sys_nice, cap_sys_resource, cap_sys_time, cap_sys_tty_config, cap_mknod, cap_lease, cap_audit_write, cap_audit_control, cap_setfcap,
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Andrew Morgan wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 KaiGai Kohei wrote: There is already a pam_cap module in the libcap2 package. Can we merge this functionality? I think it is a good idea. However, this module already have a feature to modify inheritable capability set. How does it to be described in the /etc/security/capability.conf? One idea is like a following convention: # compatible configuration. We can omit i: at the head of line cap_setfcap tak # It drops any capabilities from b-set except for cap_net_raw and cap_fowner b:cap_net_raw,cap_fownerymj # It drops only cap_dac_override from b-set. b:-cap_dac_override kaigai # It drops only cap_sys_admin from b-set of any user within users group. b:-cap_sys_admingroup:users I like the idea of a separate line for bounds. For ease of parsing, perhaps '!' or some other symbol prefix to the line could be used to identify lines that refer to cap_bound? In other modules, @groupname is used to capture a group association. Lines like this should be supported: !cap_net_raw @regularusers# suppress from cap_bset cap_net_raw @pingers morgan # add to pI where morgan is not in group @pingers but is in group @regularusers. The @groupname is intuitive convention. I also think it is good idea. But !cap_xxx is a bit misunderstandable for me. Someone may misunderstand this line means any capabilities except for cap_xxx. Thus, I think that using b: and omittable i: prefix is better than !. In addition, what is your opinion about using -b: and -i: to represent dropping capabilities currently they have? There is one more uncertain case. When a user belongs to several groups with capabilities configuration, what capabilities are to be attached for the user? e.g) When kaigai belong to @pingers and @paccters b:cap_sys_pacct @paccters b:cap_net_raw @pingers -b:cap_dac_override,cap_net_raw kaigai If we apply OR policy, kaigai get only cap_sys_pacct, because he got cap_sys_pacct and cap_net_raw came from @paccters and @pingers but cap_dac_override and cap_net_raw are dropped by the third line. Thanks, Cheers Andrew Thanks, Cheers Andrew [EMAIL PROTECTED] wrote: Quoting KaiGai Kohei ([EMAIL PROTECTED]): Serge E. Hallyn wrote: The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# Neat. A bigger-stick version of not adding the account to group wheel. I'll use that. Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. Thanks! I don't know what happened to my alias for him... thanks, -serge -- KaiGai Kohei [EMAIL PROTECTED] pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei [EMAIL PROTECTED] */ #include errno.h #include pwd.h #include stdlib.h #include
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
There is already a pam_cap module in the libcap2 package. Can we merge this functionality? I think it is a good idea. However, this module already have a feature to modify inheritable capability set. How does it to be described in the "/etc/security/capability.conf"? One idea is like a following convention: # compatible configuration. We can omit "i:" at the head of line cap_setfcap tak # It drops any capabilities from b-set except for cap_net_raw and cap_fowner b:cap_net_raw,cap_fownerymj # It drops only cap_dac_override from b-set. b:-cap_dac_override kaigai # It drops only cap_sys_admin from b-set of any user within users group. b:-cap_sys_admingroup:users Thanks, Cheers Andrew [EMAIL PROTECTED] wrote: Quoting KaiGai Kohei ([EMAIL PROTECTED]): Serge E. Hallyn wrote: The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# Neat. A bigger-stick version of not adding the account to group wheel. I'll use that. Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. Thanks! I don't know what happened to my alias for him... thanks, -serge -- KaiGai Kohei <[EMAIL PROTECTED]> pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei <[EMAIL PROTECTED]> */ #include #include #include #include #include #include #include #include #include #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif static char *captable[] = { "cap_chown", "cap_dac_override", "cap_dac_read_search", "cap_fowner", "cap_fsetid", "cap_kill", "cap_setgid", "cap_setuid", "cap_setpcap", "cap_linux_immutable", "cap_net_bind_service", "cap_net_broadcast", "cap_net_admin", "cap_net_raw", "cap_ipc_lock", "cap_ipc_owner", "cap_sys_module", "cap_sys_rawio", "cap_sys_chroot", "cap_sys_ptrace", "cap_sys_pacct", "cap_sys_admin", "cap_sys_boot", "cap_sys_nice", "cap_sys_resource", "cap_sys_time", "cap_sys_tty_config", "cap_mknod", "cap_lease", "cap_audit_write", "cap_audit_control", "cap_setfcap", NULL, }; PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { struct passwd *pwd; char *pos, *buf; char *username = NULL; /* open system logger */ openlog("pam_cap_bset", LOG_PERROR | LOG_PID, LOG_AUTHPRIV); /* get the unix username */ if (pam_get_item(pamh, PAM_USER, (void *) ) != PAM_SUCCESS || !username) return PAM_USER_UNKNOWN; /* get the passwd entry */ pwd = getpwnam(username); if
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Serge, Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? passwd(5) says the fifth field is optional and only used for informational purpose (like ulimit, umask). However, using any other separate config file is conservative and better. One candidate is "/etc/security/capability.conf" defined as the config file of pam_cap. Thanks, -- KaiGai Kohei <[EMAIL PROTECTED]> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 There is already a pam_cap module in the libcap2 package. Can we merge this functionality? Cheers Andrew [EMAIL PROTECTED] wrote: > Quoting KaiGai Kohei ([EMAIL PROTECTED]): >> Serge E. Hallyn wrote: >>> The capability bounding set is a set beyond which capabilities >>> cannot grow. Currently cap_bset is per-system. It can be >>> manipulated through sysctl, but only init can add capabilities. >>> Root can remove capabilities. By default it includes all caps >>> except CAP_SETPCAP. >> Serge, >> >> This feature makes me being interested in. >> I think you intend to apply this feature for the primary process >> of security container. >> However, it is also worthwhile to apply when a session is starting up. >> >> The following PAM module enables to drop capability bounding bit >> specified by the fifth field in /etc/passwd entry. >> This code is just an example now, but considerable feature. >> >> build and install: >> # gcc -Wall -c pam_cap_drop.c >> # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam >> # cp pam_cap_drop.so /lib/security >> >> modify /etc/passwd as follows: >> >> tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash >>^^ >> example: >> [EMAIL PROTECTED] ~]$ ping 192.168.1.1 >> PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. >> 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms >> 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms >> >> --- 192.168.1.1 ping statistics --- >> 2 packets transmitted, 2 received, 0% packet loss, time 999ms >> rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms >> >> [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] >> [EMAIL PROTECTED]'s password: >> Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx >> [EMAIL PROTECTED] ~]$ export LANG=C >> [EMAIL PROTECTED] ~]$ ping 192.168.1.1 >> ping: icmp open socket: Operation not permitted >> >> [EMAIL PROTECTED] ~]$ su >> Password: >> pam_cap_bset[6921]: user root does not have 'cap_drop=' property >> [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap >> CapInh: >> CapPrm: dffe >> CapEff: dffe >> [EMAIL PROTECTED] tak]# > > Neat. A bigger-stick version of not adding the account to > group wheel. I'll use that. > > Is there any reason not to have a separate /etc/login.capbounds > config file, though, so the account can still have a full name? > Did you only use that for convenience of proof of concept, or > is there another reason? > >> # BTW, I replaced the James's address in the Cc: list, >> # because MTA does not accept it. > > Thanks! I don't know what happened to my alias for him... > > thanks, > -serge > >> -- >> KaiGai Kohei <[EMAIL PROTECTED]> >> >> >> pam_cap_drop.c >> >> >> /* >> * pam_cap_drop.c module -- drop capabilities bounding set >> * >> * Copyright: 2007 KaiGai Kohei <[EMAIL PROTECTED]> >> */ >> >> #include >> #include >> #include >> #include >> #include >> #include >> #include >> #include >> >> #include >> >> #ifndef PR_CAPBSET_DROP >> #define PR_CAPBSET_DROP 24 >> #endif >> >> static char *captable[] = { >> "cap_chown", >> "cap_dac_override", >> "cap_dac_read_search", >> "cap_fowner", >> "cap_fsetid", >> "cap_kill", >> "cap_setgid", >> "cap_setuid", >> "cap_setpcap", >> "cap_linux_immutable", >> "cap_net_bind_service", >> "cap_net_broadcast", >> "cap_net_admin", >> "cap_net_raw", >> "cap_ipc_lock", >> "cap_ipc_owner", >> "cap_sys_module", >> "cap_sys_rawio", >> "cap_sys_chroot", >> "cap_sys_ptrace", >> "cap_sys_pacct", >> "cap_sys_admin", >> "cap_sys_boot", >> "cap_sys_nice", >> "cap_sys_resource", >> "cap_sys_time", >> "cap_sys_tty_config", >> "cap_mknod", >> "cap_lease", >> "cap_audit_write", >> "cap_audit_control", >> "cap_setfcap", >> NULL, >> }; >> >> >> PAM_EXTERN int >> pam_sm_open_session(pam_handle_t *pamh, int flags, >> int argc, const char **argv) >> { >> struct passwd *pwd; >> char *pos, *buf; >> char *username = NULL; >> >> /* open system logger */ >> openlog("pam_cap_bset", LOG_PERROR | LOG_PID, LOG_AUTHPRIV); >> >> /* get the unix username */ >> if (pam_get_item(pamh, PAM_USER, (void *) ) != PAM_SUCCESS || >> !username) >> return PAM_USER_UNKNOWN; >> >> /* get the passwd entry */ >> pwd = getpwnam(username); >> if (!pwd) >> return PAM_USER_UNKNOWN; >> >> /* Is there "cap_drop=" ? */ >> pos = strstr(pwd->pw_gecos, "cap_drop="); >> if (pos) { >> buf = strdup(pos + sizeof("cap_drop=") - 1); >> if (!buf) >> return PAM_SESSION_ERR; >>
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 There is already a pam_cap module in the libcap2 package. Can we merge this functionality? Cheers Andrew [EMAIL PROTECTED] wrote: Quoting KaiGai Kohei ([EMAIL PROTECTED]): Serge E. Hallyn wrote: The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# Neat. A bigger-stick version of not adding the account to group wheel. I'll use that. Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. Thanks! I don't know what happened to my alias for him... thanks, -serge -- KaiGai Kohei [EMAIL PROTECTED] pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei [EMAIL PROTECTED] */ #include errno.h #include pwd.h #include stdlib.h #include stdio.h #include string.h #include syslog.h #include sys/prctl.h #include sys/types.h #include security/pam_modules.h #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif static char *captable[] = { cap_chown, cap_dac_override, cap_dac_read_search, cap_fowner, cap_fsetid, cap_kill, cap_setgid, cap_setuid, cap_setpcap, cap_linux_immutable, cap_net_bind_service, cap_net_broadcast, cap_net_admin, cap_net_raw, cap_ipc_lock, cap_ipc_owner, cap_sys_module, cap_sys_rawio, cap_sys_chroot, cap_sys_ptrace, cap_sys_pacct, cap_sys_admin, cap_sys_boot, cap_sys_nice, cap_sys_resource, cap_sys_time, cap_sys_tty_config, cap_mknod, cap_lease, cap_audit_write, cap_audit_control, cap_setfcap, NULL, }; PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { struct passwd *pwd; char *pos, *buf; char *username = NULL; /* open system logger */ openlog(pam_cap_bset, LOG_PERROR | LOG_PID, LOG_AUTHPRIV); /* get the unix username */ if (pam_get_item(pamh, PAM_USER, (void *) username) != PAM_SUCCESS || !username) return PAM_USER_UNKNOWN; /* get the passwd entry */ pwd = getpwnam(username); if (!pwd) return PAM_USER_UNKNOWN; /* Is there cap_drop= ? */ pos = strstr(pwd-pw_gecos, cap_drop=); if (pos) { buf = strdup(pos + sizeof(cap_drop=) - 1); if (!buf) return PAM_SESSION_ERR; pos = strtok(buf, ,); while (pos) { int rc, i; for (i=0; captable[i]; i++) { if (!strcmp(pos, captable[i])) { rc = prctl(PR_CAPBSET_DROP, i);
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Serge, Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? passwd(5) says the fifth field is optional and only used for informational purpose (like ulimit, umask). However, using any other separate config file is conservative and better. One candidate is /etc/security/capability.conf defined as the config file of pam_cap. Thanks, -- KaiGai Kohei [EMAIL PROTECTED] -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
There is already a pam_cap module in the libcap2 package. Can we merge this functionality? I think it is a good idea. However, this module already have a feature to modify inheritable capability set. How does it to be described in the /etc/security/capability.conf? One idea is like a following convention: # compatible configuration. We can omit i: at the head of line cap_setfcap tak # It drops any capabilities from b-set except for cap_net_raw and cap_fowner b:cap_net_raw,cap_fownerymj # It drops only cap_dac_override from b-set. b:-cap_dac_override kaigai # It drops only cap_sys_admin from b-set of any user within users group. b:-cap_sys_admingroup:users Thanks, Cheers Andrew [EMAIL PROTECTED] wrote: Quoting KaiGai Kohei ([EMAIL PROTECTED]): Serge E. Hallyn wrote: The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# Neat. A bigger-stick version of not adding the account to group wheel. I'll use that. Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. Thanks! I don't know what happened to my alias for him... thanks, -serge -- KaiGai Kohei [EMAIL PROTECTED] pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei [EMAIL PROTECTED] */ #include errno.h #include pwd.h #include stdlib.h #include stdio.h #include string.h #include syslog.h #include sys/prctl.h #include sys/types.h #include security/pam_modules.h #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif static char *captable[] = { cap_chown, cap_dac_override, cap_dac_read_search, cap_fowner, cap_fsetid, cap_kill, cap_setgid, cap_setuid, cap_setpcap, cap_linux_immutable, cap_net_bind_service, cap_net_broadcast, cap_net_admin, cap_net_raw, cap_ipc_lock, cap_ipc_owner, cap_sys_module, cap_sys_rawio, cap_sys_chroot, cap_sys_ptrace, cap_sys_pacct, cap_sys_admin, cap_sys_boot, cap_sys_nice, cap_sys_resource, cap_sys_time, cap_sys_tty_config, cap_mknod, cap_lease, cap_audit_write, cap_audit_control, cap_setfcap, NULL, }; PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { struct passwd *pwd; char *pos, *buf; char *username = NULL; /* open system logger */ openlog(pam_cap_bset, LOG_PERROR | LOG_PID, LOG_AUTHPRIV); /* get the unix username */ if (pam_get_item(pamh, PAM_USER, (void *) username) != PAM_SUCCESS || !username) return PAM_USER_UNKNOWN; /* get the passwd entry */ pwd =
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Quoting KaiGai Kohei ([EMAIL PROTECTED]): > Serge E. Hallyn wrote: > > The capability bounding set is a set beyond which capabilities > > cannot grow. Currently cap_bset is per-system. It can be > > manipulated through sysctl, but only init can add capabilities. > > Root can remove capabilities. By default it includes all caps > > except CAP_SETPCAP. > > Serge, > > This feature makes me being interested in. > I think you intend to apply this feature for the primary process > of security container. > However, it is also worthwhile to apply when a session is starting up. > > The following PAM module enables to drop capability bounding bit > specified by the fifth field in /etc/passwd entry. > This code is just an example now, but considerable feature. > > build and install: > # gcc -Wall -c pam_cap_drop.c > # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam > # cp pam_cap_drop.so /lib/security > > modify /etc/passwd as follows: > > tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash >^^ > example: > [EMAIL PROTECTED] ~]$ ping 192.168.1.1 > PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. > 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms > 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms > > --- 192.168.1.1 ping statistics --- > 2 packets transmitted, 2 received, 0% packet loss, time 999ms > rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms > > [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] > [EMAIL PROTECTED]'s password: > Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx > [EMAIL PROTECTED] ~]$ export LANG=C > [EMAIL PROTECTED] ~]$ ping 192.168.1.1 > ping: icmp open socket: Operation not permitted > > [EMAIL PROTECTED] ~]$ su > Password: > pam_cap_bset[6921]: user root does not have 'cap_drop=' property > [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap > CapInh: > CapPrm: dffe > CapEff: dffe > [EMAIL PROTECTED] tak]# Neat. A bigger-stick version of not adding the account to group wheel. I'll use that. Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? > # BTW, I replaced the James's address in the Cc: list, > # because MTA does not accept it. Thanks! I don't know what happened to my alias for him... thanks, -serge > -- > KaiGai Kohei <[EMAIL PROTECTED]> > > > pam_cap_drop.c > > > /* > * pam_cap_drop.c module -- drop capabilities bounding set > * > * Copyright: 2007 KaiGai Kohei <[EMAIL PROTECTED]> > */ > > #include > #include > #include > #include > #include > #include > #include > #include > > #include > > #ifndef PR_CAPBSET_DROP > #define PR_CAPBSET_DROP 24 > #endif > > static char *captable[] = { > "cap_chown", > "cap_dac_override", > "cap_dac_read_search", > "cap_fowner", > "cap_fsetid", > "cap_kill", > "cap_setgid", > "cap_setuid", > "cap_setpcap", > "cap_linux_immutable", > "cap_net_bind_service", > "cap_net_broadcast", > "cap_net_admin", > "cap_net_raw", > "cap_ipc_lock", > "cap_ipc_owner", > "cap_sys_module", > "cap_sys_rawio", > "cap_sys_chroot", > "cap_sys_ptrace", > "cap_sys_pacct", > "cap_sys_admin", > "cap_sys_boot", > "cap_sys_nice", > "cap_sys_resource", > "cap_sys_time", > "cap_sys_tty_config", > "cap_mknod", > "cap_lease", > "cap_audit_write", > "cap_audit_control", > "cap_setfcap", > NULL, > }; > > > PAM_EXTERN int > pam_sm_open_session(pam_handle_t *pamh, int flags, > int argc, const char **argv) > { > struct passwd *pwd; > char *pos, *buf; > char *username = NULL; > > /* open system logger */ > openlog("pam_cap_bset", LOG_PERROR | LOG_PID, LOG_AUTHPRIV); > > /* get the unix username */ > if (pam_get_item(pamh, PAM_USER, (void *) ) != PAM_SUCCESS || > !username) > return PAM_USER_UNKNOWN; > > /* get the passwd entry */ > pwd = getpwnam(username); > if (!pwd) > return PAM_USER_UNKNOWN; > > /* Is there "cap_drop=" ? */ > pos = strstr(pwd->pw_gecos, "cap_drop="); > if (pos) { > buf = strdup(pos + sizeof("cap_drop=") - 1); > if (!buf) > return PAM_SESSION_ERR; > pos = strtok(buf, ","); > while (pos) { > int rc, i; > > for (i=0; captable[i]; i++) { > if (!strcmp(pos, captable[i])) { > rc =
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Serge E. Hallyn wrote: > The capability bounding set is a set beyond which capabilities > cannot grow. Currently cap_bset is per-system. It can be > manipulated through sysctl, but only init can add capabilities. > Root can remove capabilities. By default it includes all caps > except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. -- KaiGai Kohei <[EMAIL PROTECTED]> pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei <[EMAIL PROTECTED]> */ #include #include #include #include #include #include #include #include #include #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif static char *captable[] = { "cap_chown", "cap_dac_override", "cap_dac_read_search", "cap_fowner", "cap_fsetid", "cap_kill", "cap_setgid", "cap_setuid", "cap_setpcap", "cap_linux_immutable", "cap_net_bind_service", "cap_net_broadcast", "cap_net_admin", "cap_net_raw", "cap_ipc_lock", "cap_ipc_owner", "cap_sys_module", "cap_sys_rawio", "cap_sys_chroot", "cap_sys_ptrace", "cap_sys_pacct", "cap_sys_admin", "cap_sys_boot", "cap_sys_nice", "cap_sys_resource", "cap_sys_time", "cap_sys_tty_config", "cap_mknod", "cap_lease", "cap_audit_write", "cap_audit_control", "cap_setfcap", NULL, }; PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { struct passwd *pwd; char *pos, *buf; char *username = NULL; /* open system logger */ openlog("pam_cap_bset", LOG_PERROR | LOG_PID, LOG_AUTHPRIV); /* get the unix username */ if (pam_get_item(pamh, PAM_USER, (void *) ) != PAM_SUCCESS || !username) return PAM_USER_UNKNOWN; /* get the passwd entry */ pwd = getpwnam(username); if (!pwd) return PAM_USER_UNKNOWN; /* Is there "cap_drop=" ? */ pos = strstr(pwd->pw_gecos, "cap_drop="); if (pos) { buf = strdup(pos + sizeof("cap_drop=") - 1); if (!buf) return PAM_SESSION_ERR; pos = strtok(buf, ","); while (pos) { int rc, i; for (i=0; captable[i]; i++) { if (!strcmp(pos, captable[i])) { rc = prctl(PR_CAPBSET_DROP, i); if (rc < 0) { syslog(LOG_NOTICE, "user %s could not drop %s (%s)", username, captable[i], strerror(errno)); break; } syslog(LOG_NOTICE, "user %s drops %s\n", username, captable[i]); goto next; } } break;
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Quoting KaiGai Kohei ([EMAIL PROTECTED]): Serge E. Hallyn wrote: The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# Neat. A bigger-stick version of not adding the account to group wheel. I'll use that. Is there any reason not to have a separate /etc/login.capbounds config file, though, so the account can still have a full name? Did you only use that for convenience of proof of concept, or is there another reason? # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. Thanks! I don't know what happened to my alias for him... thanks, -serge -- KaiGai Kohei [EMAIL PROTECTED] pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei [EMAIL PROTECTED] */ #include errno.h #include pwd.h #include stdlib.h #include stdio.h #include string.h #include syslog.h #include sys/prctl.h #include sys/types.h #include security/pam_modules.h #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif static char *captable[] = { cap_chown, cap_dac_override, cap_dac_read_search, cap_fowner, cap_fsetid, cap_kill, cap_setgid, cap_setuid, cap_setpcap, cap_linux_immutable, cap_net_bind_service, cap_net_broadcast, cap_net_admin, cap_net_raw, cap_ipc_lock, cap_ipc_owner, cap_sys_module, cap_sys_rawio, cap_sys_chroot, cap_sys_ptrace, cap_sys_pacct, cap_sys_admin, cap_sys_boot, cap_sys_nice, cap_sys_resource, cap_sys_time, cap_sys_tty_config, cap_mknod, cap_lease, cap_audit_write, cap_audit_control, cap_setfcap, NULL, }; PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { struct passwd *pwd; char *pos, *buf; char *username = NULL; /* open system logger */ openlog(pam_cap_bset, LOG_PERROR | LOG_PID, LOG_AUTHPRIV); /* get the unix username */ if (pam_get_item(pamh, PAM_USER, (void *) username) != PAM_SUCCESS || !username) return PAM_USER_UNKNOWN; /* get the passwd entry */ pwd = getpwnam(username); if (!pwd) return PAM_USER_UNKNOWN; /* Is there cap_drop= ? */ pos = strstr(pwd-pw_gecos, cap_drop=); if (pos) { buf = strdup(pos + sizeof(cap_drop=) - 1); if (!buf) return PAM_SESSION_ERR; pos = strtok(buf, ,); while (pos) { int rc, i; for (i=0; captable[i]; i++) { if (!strcmp(pos, captable[i])) { rc = prctl(PR_CAPBSET_DROP, i); if (rc 0) { syslog(LOG_NOTICE, user %s
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Serge E. Hallyn wrote: The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. Serge, This feature makes me being interested in. I think you intend to apply this feature for the primary process of security container. However, it is also worthwhile to apply when a session is starting up. The following PAM module enables to drop capability bounding bit specified by the fifth field in /etc/passwd entry. This code is just an example now, but considerable feature. build and install: # gcc -Wall -c pam_cap_drop.c # gcc -Wall -shared -Xlinker -x -o pam_cap_drop.so pam_cap_drop.o -lpam # cp pam_cap_drop.so /lib/security modify /etc/passwd as follows: tak:x:1004:100:cap_drop=cap_net_raw,cap_chown:/home/tak:/bin/bash ^^ example: [EMAIL PROTECTED] ~]$ ping 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=1.23 ms 64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=1.02 ms --- 192.168.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 1.023/1.130/1.237/0.107 ms [EMAIL PROTECTED] ~]$ ssh [EMAIL PROTECTED] [EMAIL PROTECTED]'s password: Last login: Sat Dec 1 10:09:29 2007 from masu.myhome.cx [EMAIL PROTECTED] ~]$ export LANG=C [EMAIL PROTECTED] ~]$ ping 192.168.1.1 ping: icmp open socket: Operation not permitted [EMAIL PROTECTED] ~]$ su Password: pam_cap_bset[6921]: user root does not have 'cap_drop=' property [EMAIL PROTECTED] tak]# cat /proc/self/status | grep ^Cap CapInh: CapPrm: dffe CapEff: dffe [EMAIL PROTECTED] tak]# # BTW, I replaced the James's address in the Cc: list, # because MTA does not accept it. -- KaiGai Kohei [EMAIL PROTECTED] pam_cap_drop.c /* * pam_cap_drop.c module -- drop capabilities bounding set * * Copyright: 2007 KaiGai Kohei [EMAIL PROTECTED] */ #include errno.h #include pwd.h #include stdlib.h #include stdio.h #include string.h #include syslog.h #include sys/prctl.h #include sys/types.h #include security/pam_modules.h #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif static char *captable[] = { cap_chown, cap_dac_override, cap_dac_read_search, cap_fowner, cap_fsetid, cap_kill, cap_setgid, cap_setuid, cap_setpcap, cap_linux_immutable, cap_net_bind_service, cap_net_broadcast, cap_net_admin, cap_net_raw, cap_ipc_lock, cap_ipc_owner, cap_sys_module, cap_sys_rawio, cap_sys_chroot, cap_sys_ptrace, cap_sys_pacct, cap_sys_admin, cap_sys_boot, cap_sys_nice, cap_sys_resource, cap_sys_time, cap_sys_tty_config, cap_mknod, cap_lease, cap_audit_write, cap_audit_control, cap_setfcap, NULL, }; PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { struct passwd *pwd; char *pos, *buf; char *username = NULL; /* open system logger */ openlog(pam_cap_bset, LOG_PERROR | LOG_PID, LOG_AUTHPRIV); /* get the unix username */ if (pam_get_item(pamh, PAM_USER, (void *) username) != PAM_SUCCESS || !username) return PAM_USER_UNKNOWN; /* get the passwd entry */ pwd = getpwnam(username); if (!pwd) return PAM_USER_UNKNOWN; /* Is there cap_drop= ? */ pos = strstr(pwd-pw_gecos, cap_drop=); if (pos) { buf = strdup(pos + sizeof(cap_drop=) - 1); if (!buf) return PAM_SESSION_ERR; pos = strtok(buf, ,); while (pos) { int rc, i; for (i=0; captable[i]; i++) { if (!strcmp(pos, captable[i])) { rc = prctl(PR_CAPBSET_DROP, i); if (rc 0) { syslog(LOG_NOTICE, user %s could not drop %s (%s), username, captable[i], strerror(errno)); break; } syslog(LOG_NOTICE, user %s drops %s\n, username, captable[i]); goto next; } }
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Quoting Andrew Morgan ([EMAIL PROTECTED]): > -BEGIN PGP SIGNED MESSAGE- > Hash: SHA1 > > This looks good to me. > > [As you anticipated, there is a potential merge issue with Casey's > recent addition of MAC capabilities - which will make CAP_MAC_ADMIN the > highest allocated capability: ie., > > #define CAP_LAST_CAP CAP_MAC_ADMIN > > ]. > > Signed-off-by: Andrew G. Morgan <[EMAIL PROTECTED]> Thanks, Andrew. Yes, the following patch will be needed on top of the previous one: -serge >From 97ee046e8075a21b356fb93db0769d440437ef51 Mon Sep 17 00:00:00 2001 From: [EMAIL PROTECTED] <[EMAIL PROTECTED](none)> Date: Tue, 27 Nov 2007 10:37:57 -0800 Subject: [PATCH 1/1] capabilities: fix CAP_LAST_CAP to CAP_MAC_ADMIN A recent SMACK patch introduced two new capabilities. The capability bounding set patch defined CAP_LAST_CAP erroneously relative to that patch. Signed-off-by: Serge Hallyn <[EMAIL PROTECTED]> --- include/linux/capability.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/include/linux/capability.h b/include/linux/capability.h index 5fc3fea..7d50ff6 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -332,7 +332,7 @@ typedef struct kernel_cap_struct { #define CAP_MAC_ADMIN33 -#define CAP_LAST_CAP CAP_SETFCAP +#define CAP_LAST_CAP CAP_MAC_ADMIN #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) -- 1.5.1 - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
Quoting Andrew Morgan ([EMAIL PROTECTED]): -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 This looks good to me. [As you anticipated, there is a potential merge issue with Casey's recent addition of MAC capabilities - which will make CAP_MAC_ADMIN the highest allocated capability: ie., #define CAP_LAST_CAP CAP_MAC_ADMIN ]. Signed-off-by: Andrew G. Morgan [EMAIL PROTECTED] Thanks, Andrew. Yes, the following patch will be needed on top of the previous one: -serge From 97ee046e8075a21b356fb93db0769d440437ef51 Mon Sep 17 00:00:00 2001 From: [EMAIL PROTECTED] [EMAIL PROTECTED](none) Date: Tue, 27 Nov 2007 10:37:57 -0800 Subject: [PATCH 1/1] capabilities: fix CAP_LAST_CAP to CAP_MAC_ADMIN A recent SMACK patch introduced two new capabilities. The capability bounding set patch defined CAP_LAST_CAP erroneously relative to that patch. Signed-off-by: Serge Hallyn [EMAIL PROTECTED] --- include/linux/capability.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/include/linux/capability.h b/include/linux/capability.h index 5fc3fea..7d50ff6 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -332,7 +332,7 @@ typedef struct kernel_cap_struct { #define CAP_MAC_ADMIN33 -#define CAP_LAST_CAP CAP_SETFCAP +#define CAP_LAST_CAP CAP_MAC_ADMIN #define cap_valid(x) ((x) = 0 (x) = CAP_LAST_CAP) -- 1.5.1 - To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 This looks good to me. [As you anticipated, there is a potential merge issue with Casey's recent addition of MAC capabilities - which will make CAP_MAC_ADMIN the highest allocated capability: ie., #define CAP_LAST_CAP CAP_MAC_ADMIN ]. Signed-off-by: Andrew G. Morgan <[EMAIL PROTECTED]> Cheers Andrew Serge E. Hallyn wrote: >>From 22da6ccb1a24d1b6fa481d990a26197c6bfdfa77 Mon Sep 17 00:00:00 2001 > From: Serge E. Hallyn <[EMAIL PROTECTED]> > Date: Mon, 19 Nov 2007 13:54:05 -0500 > Subject: [PATCH 1/1] capabilities: introduce per-process capability bounding > set (v10) > > The capability bounding set is a set beyond which capabilities > cannot grow. Currently cap_bset is per-system. It can be > manipulated through sysctl, but only init can add capabilities. > Root can remove capabilities. By default it includes all caps > except CAP_SETPCAP. > > This patch makes the bounding set per-process when file > capabilities are enabled. It is inherited at fork from parent. > Noone can add elements, CAP_SETPCAP is required to remove them. > > One example use of this is to start a safer container. For > instance, until device namespaces or per-container device > whitelists are introduced, it is best to take CAP_MKNOD away > from a container. > > The bounding set will not affect pP and pE immediately. It will > only affect pP' and pE' after subsequent exec()s. It also does > not affect pI, and exec() does not constrain pI'. So to really > start a shell with no way of regain CAP_MKNOD, you would do > > prctl(PR_CAPBSET_DROP, CAP_MKNOD); > cap_t cap = cap_get_proc(); > cap_value_t caparray[1]; > caparray[0] = CAP_MKNOD; > cap_set_flag(cap, CAP_INHERITABLE, 1, caparray, CAP_DROP); > cap_set_proc(cap); > cap_free(cap); > > The following test program will get and set the bounding > set (but not pI). For instance > > ./bset get > (lists capabilities in bset) > ./bset drop cap_net_raw > (starts shell with new bset) > (use capset, setuid binary, or binary with > file capabilities to try to increase caps) > > > cap_bound.c > > #include > #include > #include > #include > #include > #include > #include > > #ifndef PR_CAPBSET_READ > #define PR_CAPBSET_READ 23 > #endif > > #ifndef PR_CAPBSET_DROP > #define PR_CAPBSET_DROP 24 > #endif > > int usage(char *me) > { > printf("Usage: %s get\n", me); > printf(" %s drop \n", me); > return 1; > } > > #define numcaps 32 > char *captable[numcaps] = { > "cap_chown", > "cap_dac_override", > "cap_dac_read_search", > "cap_fowner", > "cap_fsetid", > "cap_kill", > "cap_setgid", > "cap_setuid", > "cap_setpcap", > "cap_linux_immutable", > "cap_net_bind_service", > "cap_net_broadcast", > "cap_net_admin", > "cap_net_raw", > "cap_ipc_lock", > "cap_ipc_owner", > "cap_sys_module", > "cap_sys_rawio", > "cap_sys_chroot", > "cap_sys_ptrace", > "cap_sys_pacct", > "cap_sys_admin", > "cap_sys_boot", > "cap_sys_nice", > "cap_sys_resource", > "cap_sys_time", > "cap_sys_tty_config", > "cap_mknod", > "cap_lease", > "cap_audit_write", > "cap_audit_control", > "cap_setfcap" > }; > > int getbcap(void) > { > int comma=0; > unsigned long i; > int ret; > > printf("i know of %d capabilities\n", numcaps); > printf("capability bounding set:"); > for (i=0; i ret = prctl(PR_CAPBSET_READ, i); > if (ret < 0) > perror("prctl"); > else if (ret==1) > printf("%s%s", (comma++) ? ", " : " ", captable[i]); > } > printf("\n"); > return 0; > } > > int capdrop(char *str) > { > unsigned long i; > > int found=0; > for (i=0; i if (strcmp(captable[i], str) == 0) { > found=1; > break; > } > } > if (!found) > return 1; > if (prctl(PR_CAPBSET_DROP, i)) { > perror("prctl"); > return 1; > } > return 0; > } > > int main(int argc, char *argv[]) > { > if (argc<2) > return usage(argv[0]); > if (strcmp(argv[1], "get")==0) > return getbcap(); > if (strcmp(argv[1], "drop")!=0 || argc<3) > return usage(argv[0]); > if (capdrop(argv[2])) { > printf("unknown capability\n"); > return 1; > } > return execl("/bin/bash", "/bin/bash", NULL); > } > > >
[PATCH] capabilities: introduce per-process capability bounding set (v10)
>From 22da6ccb1a24d1b6fa481d990a26197c6bfdfa77 Mon Sep 17 00:00:00 2001 From: Serge E. Hallyn <[EMAIL PROTECTED]> Date: Mon, 19 Nov 2007 13:54:05 -0500 Subject: [PATCH 1/1] capabilities: introduce per-process capability bounding set (v10) The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. This patch makes the bounding set per-process when file capabilities are enabled. It is inherited at fork from parent. Noone can add elements, CAP_SETPCAP is required to remove them. One example use of this is to start a safer container. For instance, until device namespaces or per-container device whitelists are introduced, it is best to take CAP_MKNOD away from a container. The bounding set will not affect pP and pE immediately. It will only affect pP' and pE' after subsequent exec()s. It also does not affect pI, and exec() does not constrain pI'. So to really start a shell with no way of regain CAP_MKNOD, you would do prctl(PR_CAPBSET_DROP, CAP_MKNOD); cap_t cap = cap_get_proc(); cap_value_t caparray[1]; caparray[0] = CAP_MKNOD; cap_set_flag(cap, CAP_INHERITABLE, 1, caparray, CAP_DROP); cap_set_proc(cap); cap_free(cap); The following test program will get and set the bounding set (but not pI). For instance ./bset get (lists capabilities in bset) ./bset drop cap_net_raw (starts shell with new bset) (use capset, setuid binary, or binary with file capabilities to try to increase caps) cap_bound.c #include #include #include #include #include #include #include #ifndef PR_CAPBSET_READ #define PR_CAPBSET_READ 23 #endif #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif int usage(char *me) { printf("Usage: %s get\n", me); printf(" %s drop \n", me); return 1; } #define numcaps 32 char *captable[numcaps] = { "cap_chown", "cap_dac_override", "cap_dac_read_search", "cap_fowner", "cap_fsetid", "cap_kill", "cap_setgid", "cap_setuid", "cap_setpcap", "cap_linux_immutable", "cap_net_bind_service", "cap_net_broadcast", "cap_net_admin", "cap_net_raw", "cap_ipc_lock", "cap_ipc_owner", "cap_sys_module", "cap_sys_rawio", "cap_sys_chroot", "cap_sys_ptrace", "cap_sys_pacct", "cap_sys_admin", "cap_sys_boot", "cap_sys_nice", "cap_sys_resource", "cap_sys_time", "cap_sys_tty_config", "cap_mknod", "cap_lease", "cap_audit_write", "cap_audit_control", "cap_setfcap" }; int getbcap(void) { int comma=0; unsigned long i; int ret; printf("i know of %d capabilities\n", numcaps); printf("capability bounding set:"); for (i=0; i --- include/linux/capability.h | 11 +-- include/linux/init_task.h | 12 include/linux/prctl.h |4 include/linux/sched.h |2 +- include/linux/security.h |5 - include/linux/sysctl.h |3 --- kernel/fork.c |1 + kernel/sys.c | 13 - kernel/sysctl.c| 35 --- kernel/sysctl_check.c |7 --- security/commoncap.c | 44 +++- 11 files changed, 66 insertions(+), 71 deletions(-) diff --git a/include/linux/capability.h b/include/linux/capability.h index a1d93da..ffe7bab 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -152,7 +152,9 @@ typedef struct kernel_cap_struct { * Transfer any capability in your permitted set to any pid, * remove any capability in your permitted set from any pid * With VFS support for capabilities (neither of above, but) - * Add any capability to the current process' inheritable set + * Add any capability from current's capability bounding set + * to the current process' inheritable set + * Allow taking bits out of capability bounding set */ #define CAP_SETPCAP 8 @@ -202,7 +204,6 @@ typedef struct kernel_cap_struct { #define CAP_IPC_OWNER15 /* Insert and remove kernel modules - modify kernel without limit */ -/* Modify cap_bset */ #define CAP_SYS_MODULE 16 /* Allow ioperm/iopl access */ @@ -314,6 +315,10 @@ typedef struct kernel_cap_struct { #define CAP_SETFCAP 31 +#define CAP_LAST_CAP CAP_SETFCAP + +#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) +
[PATCH] capabilities: introduce per-process capability bounding set (v10)
From 22da6ccb1a24d1b6fa481d990a26197c6bfdfa77 Mon Sep 17 00:00:00 2001 From: Serge E. Hallyn [EMAIL PROTECTED] Date: Mon, 19 Nov 2007 13:54:05 -0500 Subject: [PATCH 1/1] capabilities: introduce per-process capability bounding set (v10) The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. This patch makes the bounding set per-process when file capabilities are enabled. It is inherited at fork from parent. Noone can add elements, CAP_SETPCAP is required to remove them. One example use of this is to start a safer container. For instance, until device namespaces or per-container device whitelists are introduced, it is best to take CAP_MKNOD away from a container. The bounding set will not affect pP and pE immediately. It will only affect pP' and pE' after subsequent exec()s. It also does not affect pI, and exec() does not constrain pI'. So to really start a shell with no way of regain CAP_MKNOD, you would do prctl(PR_CAPBSET_DROP, CAP_MKNOD); cap_t cap = cap_get_proc(); cap_value_t caparray[1]; caparray[0] = CAP_MKNOD; cap_set_flag(cap, CAP_INHERITABLE, 1, caparray, CAP_DROP); cap_set_proc(cap); cap_free(cap); The following test program will get and set the bounding set (but not pI). For instance ./bset get (lists capabilities in bset) ./bset drop cap_net_raw (starts shell with new bset) (use capset, setuid binary, or binary with file capabilities to try to increase caps) cap_bound.c #include sys/prctl.h #include linux/capability.h #include sys/types.h #include unistd.h #include stdio.h #include stdlib.h #include string.h #ifndef PR_CAPBSET_READ #define PR_CAPBSET_READ 23 #endif #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif int usage(char *me) { printf(Usage: %s get\n, me); printf( %s drop capability\n, me); return 1; } #define numcaps 32 char *captable[numcaps] = { cap_chown, cap_dac_override, cap_dac_read_search, cap_fowner, cap_fsetid, cap_kill, cap_setgid, cap_setuid, cap_setpcap, cap_linux_immutable, cap_net_bind_service, cap_net_broadcast, cap_net_admin, cap_net_raw, cap_ipc_lock, cap_ipc_owner, cap_sys_module, cap_sys_rawio, cap_sys_chroot, cap_sys_ptrace, cap_sys_pacct, cap_sys_admin, cap_sys_boot, cap_sys_nice, cap_sys_resource, cap_sys_time, cap_sys_tty_config, cap_mknod, cap_lease, cap_audit_write, cap_audit_control, cap_setfcap }; int getbcap(void) { int comma=0; unsigned long i; int ret; printf(i know of %d capabilities\n, numcaps); printf(capability bounding set:); for (i=0; inumcaps; i++) { ret = prctl(PR_CAPBSET_READ, i); if (ret 0) perror(prctl); else if (ret==1) printf(%s%s, (comma++) ? , : , captable[i]); } printf(\n); return 0; } int capdrop(char *str) { unsigned long i; int found=0; for (i=0; inumcaps; i++) { if (strcmp(captable[i], str) == 0) { found=1; break; } } if (!found) return 1; if (prctl(PR_CAPBSET_DROP, i)) { perror(prctl); return 1; } return 0; } int main(int argc, char *argv[]) { if (argc2) return usage(argv[0]); if (strcmp(argv[1], get)==0) return getbcap(); if (strcmp(argv[1], drop)!=0 || argc3) return usage(argv[0]); if (capdrop(argv[2])) { printf(unknown capability\n); return 1; } return execl(/bin/bash, /bin/bash, NULL); } Signed-off-by: Serge E. Hallyn [EMAIL PROTECTED] --- include/linux/capability.h | 11 +-- include/linux/init_task.h | 12 include/linux/prctl.h |4 include/linux/sched.h |2 +- include/linux/security.h |5 - include/linux/sysctl.h |3 --- kernel/fork.c |1 + kernel/sys.c | 13 - kernel/sysctl.c| 35 --- kernel/sysctl_check.c |7 ---
Re: [PATCH] capabilities: introduce per-process capability bounding set (v10)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 This looks good to me. [As you anticipated, there is a potential merge issue with Casey's recent addition of MAC capabilities - which will make CAP_MAC_ADMIN the highest allocated capability: ie., #define CAP_LAST_CAP CAP_MAC_ADMIN ]. Signed-off-by: Andrew G. Morgan [EMAIL PROTECTED] Cheers Andrew Serge E. Hallyn wrote: From 22da6ccb1a24d1b6fa481d990a26197c6bfdfa77 Mon Sep 17 00:00:00 2001 From: Serge E. Hallyn [EMAIL PROTECTED] Date: Mon, 19 Nov 2007 13:54:05 -0500 Subject: [PATCH 1/1] capabilities: introduce per-process capability bounding set (v10) The capability bounding set is a set beyond which capabilities cannot grow. Currently cap_bset is per-system. It can be manipulated through sysctl, but only init can add capabilities. Root can remove capabilities. By default it includes all caps except CAP_SETPCAP. This patch makes the bounding set per-process when file capabilities are enabled. It is inherited at fork from parent. Noone can add elements, CAP_SETPCAP is required to remove them. One example use of this is to start a safer container. For instance, until device namespaces or per-container device whitelists are introduced, it is best to take CAP_MKNOD away from a container. The bounding set will not affect pP and pE immediately. It will only affect pP' and pE' after subsequent exec()s. It also does not affect pI, and exec() does not constrain pI'. So to really start a shell with no way of regain CAP_MKNOD, you would do prctl(PR_CAPBSET_DROP, CAP_MKNOD); cap_t cap = cap_get_proc(); cap_value_t caparray[1]; caparray[0] = CAP_MKNOD; cap_set_flag(cap, CAP_INHERITABLE, 1, caparray, CAP_DROP); cap_set_proc(cap); cap_free(cap); The following test program will get and set the bounding set (but not pI). For instance ./bset get (lists capabilities in bset) ./bset drop cap_net_raw (starts shell with new bset) (use capset, setuid binary, or binary with file capabilities to try to increase caps) cap_bound.c #include sys/prctl.h #include linux/capability.h #include sys/types.h #include unistd.h #include stdio.h #include stdlib.h #include string.h #ifndef PR_CAPBSET_READ #define PR_CAPBSET_READ 23 #endif #ifndef PR_CAPBSET_DROP #define PR_CAPBSET_DROP 24 #endif int usage(char *me) { printf(Usage: %s get\n, me); printf( %s drop capability\n, me); return 1; } #define numcaps 32 char *captable[numcaps] = { cap_chown, cap_dac_override, cap_dac_read_search, cap_fowner, cap_fsetid, cap_kill, cap_setgid, cap_setuid, cap_setpcap, cap_linux_immutable, cap_net_bind_service, cap_net_broadcast, cap_net_admin, cap_net_raw, cap_ipc_lock, cap_ipc_owner, cap_sys_module, cap_sys_rawio, cap_sys_chroot, cap_sys_ptrace, cap_sys_pacct, cap_sys_admin, cap_sys_boot, cap_sys_nice, cap_sys_resource, cap_sys_time, cap_sys_tty_config, cap_mknod, cap_lease, cap_audit_write, cap_audit_control, cap_setfcap }; int getbcap(void) { int comma=0; unsigned long i; int ret; printf(i know of %d capabilities\n, numcaps); printf(capability bounding set:); for (i=0; inumcaps; i++) { ret = prctl(PR_CAPBSET_READ, i); if (ret 0) perror(prctl); else if (ret==1) printf(%s%s, (comma++) ? , : , captable[i]); } printf(\n); return 0; } int capdrop(char *str) { unsigned long i; int found=0; for (i=0; inumcaps; i++) { if (strcmp(captable[i], str) == 0) { found=1; break; } } if (!found) return 1; if (prctl(PR_CAPBSET_DROP, i)) { perror(prctl); return 1; } return 0; } int main(int argc, char *argv[]) { if (argc2) return usage(argv[0]); if (strcmp(argv[1], get)==0) return getbcap(); if (strcmp(argv[1], drop)!=0 || argc3) return usage(argv[0]); if (capdrop(argv[2])) { printf(unknown capability\n); return 1; } return execl(/bin/bash, /bin/bash, NULL); } Signed-off-by: Serge E. Hallyn [EMAIL PROTECTED] --- include/linux/capability.h | 11 +-- include/linux/init_task.h | 12