Fabio,

Fabio M. Di Nitto wrote:
> Hi Jan,
> 
> I have few comments...
> 
> On Thu, 2009-05-14 at 11:49 +0200, Jan Friesse wrote:
> 
>>
>>
>>
>>
>> differences
>> between files
>> attachment
>> (corosync-support-for-uidgid-try2.patch)
>>
>> diff --git a/trunk/exec/main.c b/trunk/exec/main.c
>> index db22e96..2b41111 100644
>> --- a/trunk/exec/main.c
>> +++ b/trunk/exec/main.c
>> @@ -138,6 +138,18 @@ static void sigusr2_handler (int num)
>>         }
>>  }
>>  
>> +static void corosync_remove_uidgid_list (void) {
>> +       struct list_head *iter;
>> +
>> +       for (iter = ug_config.uidgid_list.next; iter !=
>> &ug_config.uidgid_list; ) {
>> +               struct uidgid_item *ugi = list_entry (iter, struct
>> uidgid_item, list);
>> +               iter = iter->next;
>> +
>> +               list_del (&ugi->list);
>> +               free (ugi);
>> +       }
>> +}
>> +
>>  /*
>>   * TODO this function needs some love
>>   */
>> @@ -150,6 +162,10 @@ void corosync_request_shutdown (void)
>>         poll_stop (0);
>>         totempg_finalize ();
>>         coroipcs_ipc_exit ();
>> +
>> +       /*Remove uidgid_list*/
>> +       corosync_remove_uidgid_list ();
> 
> Is there really a need to free this list on exit? we are about to abort
> anyway and the kernel will take care of that.
> 

No it's not needed. I can throw it away.

>> +
>>         corosync_exit_error (AIS_DONE_EXIT);
>>  }
>>  
>> @@ -482,12 +498,18 @@ static coroipcs_handler_fn_lvalue
>> corosync_handler_fn_get (unsigned int service,
>>  
>>  static int corosync_security_valid (int euid, int egid)
>>  {
>> +       struct list_head *iter;
>>         if (euid == 0 || egid == 0) {
>>                 return (1);
>>         }
>> -       if (euid == ug_config.uid || egid == ug_config.gid) {
>> -               return (1);
>> +
>> +       for (iter = ug_config.uidgid_list.next; iter !=
>> &ug_config.uidgid_list; iter = iter->next) {
>> +               struct uidgid_item *ugi = list_entry (iter, struct
>> uidgid_item, list);
>> +
>> +               if (euid == ugi->uid || egid == ugi->gid)
>> +                       return (1);
>>         }
>> +
>>         return (0);
>>  }
> 
> It's entirely possible that I misunderstood but aren't we looking here
> to allow a certain process name to access IPC via certain uid/gid?
> 
> Let say that we drop a file in /etc/corosync/uidgid.d/cman with uid/gid
> foo:foo, it means to me that a process called cman (or identified as
> such) is allowed to access corosync IPC with uid/gid foo:foo.

More or less, yes. If there will be process cman (or every other) with 
uid or gid foo, it will be able to use corosync. It's only 
ug_config.uid/gid enhancement. See 
https://bugzilla.redhat.com/show_bug.cgi?id=484047.


> 
> With this check I can see the possibility that a user X can get access
> to IPC because somebody else did drop a file in there... not really sure
> that's what you want.
> 
Question similar to this, I asked in some previous mail. Answer was, 
only root has access to that directory -> shouldn't be security problem.

>>  
>> diff --git a/trunk/exec/mainconfig.c b/trunk/exec/mainconfig.c
>> index 79e01cd..eb0563c 100644
>> --- a/trunk/exec/mainconfig.c
>> +++ b/trunk/exec/mainconfig.c
>> @@ -671,6 +671,54 @@ static void add_logsys_config_notification(
>>  
>>  }
>>  
>> +static int corosync_main_config_read_uidgid (
>> +       struct objdb_iface_ver0 *objdb,
>> +       const char **error_string,
>> +       struct ug_config *ug_config)
>> +{
>> +       hdb_handle_t object_find_handle;
>> +       hdb_handle_t object_service_handle;
>> +       char *value;
>> +       int uid, gid;
>> +       struct uidgid_item *ugi;
>> +
>> +       list_init (&ug_config->uidgid_list);
>> +
>> +       objdb->object_find_create (
>> +               OBJECT_PARENT_HANDLE,
>> +               "uidgid",
>> +               strlen ("uidgid"),
>> +               &object_find_handle);
>> +
>> +       while (objdb->object_find_next (
>> +               object_find_handle,
>> +               &object_service_handle) == 0) {
>> +               uid = -1;
>> +               gid = -1;
>> +
>> +               if (!objdb_get_string (objdb,object_service_handle,
>> "uid", &value)) {
>> +                       uid = uid_determine(value);
>> +               }
>> +
>> +               if (!objdb_get_string (objdb,object_service_handle,
>> "gid", &value)) {
>> +                       gid = gid_determine(value);
>> +               }
>> +
>> +               if (uid > -1 || gid > -1) {
>> +                       ugi = malloc (sizeof (*ugi));
>> +                       if (ugi == NULL) {
>> +                               _corosync_out_of_memory_error();
>> +                       }
>> +                       ugi->uid = uid;
>> +                       ugi->gid = gid;
>> +                       list_add (&ugi->list,
>> &ug_config->uidgid_list);
>> +               }
>> +       }
>> +       objdb->object_find_destroy (object_find_handle);
>> +
>> +       return 0;
>> +}
>> +
> 
> For the sake of tracking, it would be a good idea to have a record of
> what service/file did open for a certain uid/gid set.
> 
> So perhaps add an objdb entry with the name of the file and record the
> values both as strings and numeric (easier to read in debugging).
> 
> It adds a bit of complexity to code but imho it's worth the pain.
> 
> For example:
> 
> /etc/corosync/uidgid.d/foo
> 
> contains:
> 
> uidgid {
>       uid: root
>       gid: whatever
> }
> 
> it will automatically translate to (into the objdb):
> 
> uidgid {
>       uid: 0
>       gid: $random_number
>       service: foo
>       file: /etc/corosync/uidgid.d/foo
>       uid_requested: root      (uid_r or whatever keyname)
>       gid_requested: whatever   ^^ same as above
> }
> 
> a configfile could also contain more than one set:
> 
> cat /etc/corosync/uidgid.d/many
> 
> uidgid {
>       service: foo
>       uid: root
>       gid: root
> }
> uidgid {
>       service: cman
>       uid: ais
>       gid: ais
> }
> 
> that would translate to this in the objdb:
> 
> uidgid {
>       uid: 0
>       gid: 0
>       service: foo
>       file: /etc/corosync/uidgid.d/many
>       uid_requested: root      (uid_r or whatever keyname)
>       gid_requested: root   ^^ same as above
> }
> uidgid {
>       uid: $random_number
>       gid: $random_number
>       service: cman
>       file: /etc/corosync/uidgid.d/many
>       uid_requested: ais      (uid_r or whatever keyname)
>       gid_requested: ais   ^^ same as above
> }
> 
> 

Really don't understand the purpose of that.

>> diff --git a/trunk/exec/mainconfig.h b/trunk/exec/mainconfig.h
>> index c9ab7ea..26135ad 100644
>> --- a/trunk/exec/mainconfig.h
>> +++ b/trunk/exec/mainconfig.h
>> @@ -37,6 +37,7 @@
>>  
>>  #include <corosync/engine/objdb.h>
>>  #include <corosync/engine/logsys.h>
>> +#include <corosync/list.h>
>>  
>>  /*
>>   * All service handlers in the AIS
>> @@ -49,14 +50,29 @@ struct dynamic_service {
>>  };
>>  #define MAX_DYNAMIC_SERVICES 128
>>  
>> +/*
>> + * Structure describing cached uidgid item
>> + */
>> +struct uidgid_item {
>> +       struct list_head list;
>> +       int uid;
>> +       int gid;
>> +};
>> +
>>  struct ug_config {
>>         /*
>>          * user/group to run as
>>          */
>>         int uid;
>>         int gid;
>> +
>> +       /*
>> +        * Allowed users/group to connect. This is of type uidgid
>> item.
>> +        */
>> +       struct list_head uidgid_list;
>>  };
> 
> Do we need to have 2 structs? at this point one should be plenty?
> 
> struct uidgid {
>       struct list_head list;
>       int uid;
>       int gid;
> }
> 
> and init the first one to match corosync default conf.

ug_config uid/gid is used for something different. This is used (or 
should/will/was use/d) for corosync. So in previous version, user was 
able to run corosync (not process communicating with corosync) as user 
ais:ais.

This is only for authentification of process which is trying to 
communicate with corosync (using corosync lib).

Please look at https://bugzilla.redhat.com/show_bug.cgi?id=484047.

> 
> The loader should make sure to filter the config entries to load only
> uidgid entries (maybe it's already there and I haven't noticed).

Answered in some previous mail by Steve, that we don't care. But yes, 
this can be done.

> 
> Fabio
> 
> 
> 

Honza
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to