3131#define STAT_NAME_SIZE 32
3232#define STAT_DATA_SIZE 256
3333
34- static int verify_start_time ( struct subject * subject )
34+ int get_start_time ( pid_t pid , uint64_t * start )
3535{
36- /* Get the pid start time from /proc/stat and compare it with the value in
37- * the request. Return -1 if no match. */
36+ /* Get the pid start time from /proc/stat. */
3837
3938 char namebuf [STAT_NAME_SIZE ];
4039 char databuf [STAT_DATA_SIZE ];
4140 int r ;
42- FILE * f ;
41+ FILE * f = NULL ;
4342 char * p , * endp = NULL ;
4443 int i ;
4544 uint64_t start_time ;
4645
47- r = snprintf (namebuf , STAT_NAME_SIZE , "/proc/%d/stat" , subject -> data . p . pid );
46+ r = snprintf (namebuf , STAT_NAME_SIZE , "/proc/%d/stat" , pid );
4847 if (r < 0 || r >= STAT_NAME_SIZE )
4948 return - EINVAL ;
5049
@@ -54,28 +53,61 @@ static int verify_start_time(struct subject *subject)
5453 return - EINVAL ;
5554
5655 p = fgets (databuf , STAT_DATA_SIZE , f );
57- if (p == NULL )
58- return - EINVAL ;
56+ if (p == NULL ) {
57+ r = - EINVAL ;
58+ goto end ;
59+ }
5960
6061 /* read the 22th field, which is the process start time in jiffies */
6162
6263 /* skip over the "comm" field that has parentheses */
6364 p = strchr (p , ')' );
6465
65- if (* p == '\0' )
66- return - EINVAL ;
66+ if (* p == '\0' ) {
67+ r = - EINVAL ;
68+ goto end ;
69+ }
70+ p ++ ;
6771
6872 /* That was the second field. Then skip over 19 more (20 spaces). */
6973
7074 for (i = 0 ; i < 20 ; i ++ ) {
7175 p = strchr (p , ' ' );
72- if (* p == '\0' )
73- return - EINVAL ;
76+ if (* p == '\0' ) {
77+ r = - EINVAL ;
78+ goto end ;
79+ }
80+ p ++ ;
7481 }
7582
7683 start_time = strtoul (p , & endp , 10 );
77- if (endp != NULL )
78- return - EINVAL ;
84+
85+ if (endp == NULL || * endp != ' ' ) {
86+ r = - EINVAL ;
87+ goto end ;
88+ }
89+
90+ * start = start_time ;
91+ r = 0 ;
92+
93+ end :
94+ if (f )
95+ fclose (f );
96+
97+ return r ;
98+ }
99+
100+ static int verify_start_time (struct subject * subject )
101+ {
102+ int r ;
103+ uint64_t start_time = 0 ;
104+
105+ /* Compare pid start time with the value in the request. Return -1
106+ * if no match. */
107+
108+ r = get_start_time (subject -> data .p .pid , & start_time );
109+ if (r < 0 )
110+ return r ;
79111
80112 if (start_time != subject -> data .p .start_time )
81113 return - EINVAL ;
@@ -93,7 +125,8 @@ bool check_allowed(sd_bus *bus, struct conf_data *conf_data,
93125 sd_bus_creds * creds = NULL ;
94126 gid_t primary_gid ;
95127 uint64_t mask = SD_BUS_CREDS_SUPPLEMENTARY_GIDS | SD_BUS_CREDS_AUGMENT
96- | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID | SD_BUS_CREDS_UID ;
128+ | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID | SD_BUS_CREDS_UID
129+ | SD_BUS_CREDS_EUID ;
97130 const gid_t * gids = NULL ;
98131 int n_gids = 0 ;
99132 uid_t ruid , euid ;
@@ -165,10 +198,8 @@ bool check_allowed(sd_bus *bus, struct conf_data *conf_data,
165198 break ;
166199
167200 case SUBJECT_KIND_SYSTEM_BUS_NAME :
168- if (bus == NULL ) {
169- r = - EINVAL ;
201+ if (bus == NULL )
170202 goto end ;
171- }
172203
173204 r = sd_bus_get_name_creds (bus , subject -> data .b .system_bus_name , mask , & creds );
174205 if (r < 0 )
@@ -216,7 +247,7 @@ bool check_allowed(sd_bus *bus, struct conf_data *conf_data,
216247 if (gids [j ] == primary_gid ) {
217248 /* We only include supplementary gids in the check, not the
218249 primary gid. This is to make it more difficult for
219- processes to exec a setgid process to gain elevated
250+ processes to exec a setgid binary to gain elevated
220251 group access. */
221252 continue ;
222253 }
@@ -396,6 +427,22 @@ void print_decision(struct subject *subject, const char *action_id, bool allowed
396427 }
397428}
398429
430+ void print_config (struct conf_data * conf_data )
431+ {
432+ int i , j ;
433+
434+ if (conf_data == NULL )
435+ return ;
436+
437+ for (i = 0 ; i < conf_data -> n_lines ; i ++ ) {
438+ fprintf (stdout , "id: %s, groups: " , conf_data -> lines [i ].id );
439+ for (j = 0 ; j < conf_data -> lines [i ].n_groups ; j ++ ) {
440+ fprintf (stdout , "%s " , conf_data -> lines [i ].groups [j ]);
441+ }
442+ fprintf (stdout , "\n" );
443+ }
444+ }
445+
399446static int method_check_authorization (sd_bus_message * m , void * userdata , sd_bus_error * ret_error )
400447{
401448 int r ;
@@ -598,7 +645,7 @@ static int property_backend_version(sd_bus *bus, const char *path,
598645 const char * interface , const char * property , sd_bus_message * reply ,
599646 void * userdata , sd_bus_error * error )
600647{
601- return sd_bus_message_append (reply , "s" , "0.1 " );
648+ return sd_bus_message_append (reply , "s" , "2.0 " );
602649}
603650
604651static int property_backend_features (sd_bus * bus , const char * path ,
@@ -840,17 +887,3 @@ int load_directory(struct conf_data *conf_data, const char *dirname)
840887 closedir (dir );
841888 return r ;
842889}
843-
844- const char * find_policy_file ()
845- {
846- struct stat s ;
847- const char * dynamic_conf = "/etc/groupcheck.policy" ;
848- const char * default_conf = "/usr/share/defaults/etc/groupcheck.policy" ;
849-
850- if (stat (dynamic_conf , & s ) == 0 )
851- return dynamic_conf ;
852- else if (stat (default_conf , & s ) == 0 )
853- return default_conf ;
854-
855- return NULL ;
856- }
0 commit comments