3 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved
5 * Contact: Bumjin Im <bj.im@samsung.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License
27 #include <sys/types.h>
29 #include <sys/smack.h>
31 #include <security-server-cookie.h>
32 #include <security-server-comm.h>
33 #include <smack-check.h>
35 /* Delete useless cookie item *
36 * then connect prev and next */
37 void free_cookie_item(cookie_list *cookie)
40 free(cookie->permissions);
41 free(cookie->smack_label);
42 if(cookie->prev != NULL)
43 cookie->prev->next = cookie->next;
44 if(cookie->next != NULL)
45 cookie->next->prev = cookie->prev;
49 /* Cut the link of the current cookie item and connect previous link and next line *
50 * That is remove a cookie item *
51 * Returns next cookie item if exist, NULL for no more cookie item */
52 cookie_list *delete_cookie_item(cookie_list *cookie)
54 cookie_list *retval = NULL;
57 SEC_SVR_DBG("%s", "Cannot delete null cookie");
61 /* Reconnect cookie item */
62 if(cookie->next != NULL)
64 cookie->prev->next = cookie->next;
65 cookie->next->prev = cookie->prev;
66 retval = cookie->next;
70 cookie->prev->next = NULL;
73 free_cookie_item(cookie);
77 cookie_list * garbage_collection(cookie_list *cookie)
80 cookie_list *retval = NULL;
86 /* Skip default cookie */
90 /* Try to find the PID directory from proc fs */
91 snprintf(path, sizeof(path), "/proc/%d", cookie->pid);
93 ret = stat(path, &statbuf);
96 /* If it's not exist, delete the cookie */
99 SEC_SVR_DBG("Garbage found. PID:%d, deleting...", cookie->pid);
100 cookie = delete_cookie_item(cookie);
105 /* Some error occurred */
106 SEC_SVR_DBG("Error occurred on stat: errno = %d", errno);
112 /* This is not a garbage. returning */
119 /* Search existing cookie from the cookie list for the client process *
120 * At the same time, it collects garbage cookie which PID is no longer exist and delete them */
121 cookie_list *search_existing_cookie(int pid, const cookie_list *c_list)
123 cookie_list *current =(cookie_list *)c_list, *cookie = NULL;
124 char *exe = NULL, *debug_cmdline = NULL;
126 /* Search from the list */
127 while(current != NULL)
129 /* print_cookie(current);*/
130 current = garbage_collection(current);
134 /* PID must be same */
135 if(current->pid == pid)
137 /* Found cookie for the pid. Check the cookie is reused by dirrent executable */
138 /* Check the path of the process */
139 exe = read_exe_path_from_proc(pid);
142 SEC_SVR_DBG("%s", "cannot read cmdline");
145 /* Check the path is different. */
146 if(strcmp(exe, current->path) != 0)
148 /* Delete cookie for reused pid. This is an extremely rare situation. */
149 SEC_SVR_DBG("Pid [%d] for exec [%s] has been reused by [%s]. Deleting the old cookie.", pid, current->path, exe);
150 current = delete_cookie_item(current);
154 SEC_SVR_DBG("%s", "cookie found");
164 current = current->next;
169 /* Search existing cookie from the cookie list for matching pid *
170 * Default cookie (meaning PID 0) is not allowed in here */
171 cookie_list *search_cookie_from_pid(cookie_list *c_list, int pid)
173 cookie_list *current = (cookie_list *)c_list, *retval = NULL;
175 /* Search from the list */
176 while(current != NULL)
178 /* print_cookie(current);*/
179 /* PID must be same */
180 current = garbage_collection(current);
184 if(current->pid == pid)
186 SEC_SVR_DBG("%s", "cookie has been found");
190 current = current->next;
196 /* Search existing cookie from the cookie list for matching cookie and privilege */
197 /* If privilege is 0, just search cookie exists or not */
198 cookie_list *search_cookie(const cookie_list *c_list, const unsigned char *cookie, int * privileges, int privilegesSize)
200 cookie_list *current = (cookie_list *)c_list, *retval = NULL;
203 /* Search from the list */
204 while(current != NULL)
206 /* print_cookie(current);*/
207 /* PID must be same */
208 current = garbage_collection(current);
212 //searching for cookie
213 if(memcmp(current->cookie, cookie, SECURITY_SERVER_COOKIE_LEN) == 0)
215 SEC_SVR_DBG("%s", "Cookie has been found");
217 //check if this cookie belongs to root process (root process created it)
218 if(current->is_roots_process == 1)
220 SEC_SVR_DBG("%s", "Root process cookie, special privileges");
221 //we can skip privilege checking
226 if((privileges == NULL) || (privilegesSize == 0))
228 SEC_SVR_DBG("%s", "No privileges to search in cookie!");
230 else if(current->permissions == NULL)
232 SEC_SVR_DBG("%s", "Cookie has no privileges inside!");
236 SEC_SVR_DBG("%s", "Searching for privileges");
237 SEC_SVR_DBG("%s %d", "Privileges in cookie:", current->permission_len);
238 SEC_SVR_DBG("%s %d", "Privileges to search:", privilegesSize);
240 for(j = 0; j < privilegesSize; j++)
242 for(i = 0; i < current->permission_len; i++)
244 if(privileges[j] == current->permissions[i])
246 SEC_SVR_DBG("Found privilege %d", privileges[j]);
254 current = current->next;
261 cookie_list *search_cookie_new(const cookie_list *c_list,
262 const unsigned char *cookie,
264 const char *access_rights)
266 cookie_list *current = (cookie_list *)c_list, *retval = NULL;
269 /* Search from the list */
270 while(current != NULL)
272 /* print_cookie(current);*/
273 /* PID must be same */
274 current = garbage_collection(current);
278 if(memcmp(current->cookie, cookie, SECURITY_SERVER_COOKIE_LEN) == 0)
280 SEC_SVR_DBG("%s", "cookie has been found");
283 ret = smack_have_access(current->smack_label, object, access_rights);
284 SEC_SVR_DBG("SMACK have access returned %d", ret);
285 SEC_SVR_DBG("SS_SMACK: subject=%s, object=%s, access=%s, result=%d", current->smack_label, object, access_rights, ret);
297 current = current->next;
304 /* Generage a random stream value of size to cookie *
305 * by reading /dev/uranddom file */
306 int generate_random_cookie(unsigned char *cookie, int size)
310 if (cookie == NULL) {
311 SEC_SVR_DBG("%s", "Null pointer passed to function");
312 return SECURITY_SERVER_ERROR_UNKNOWN;
314 fd = open("/dev/urandom", O_RDONLY);
317 SEC_SVR_DBG("%s", "Cannot open /dev/urandom");
318 return SECURITY_SERVER_ERROR_FILE_OPERATION;
320 ret = TEMP_FAILURE_RETRY(read(fd, cookie, size));
323 SEC_SVR_DBG("Cannot read /dev/urandom: %d", ret);
324 ret = SECURITY_SERVER_ERROR_FILE_OPERATION;
327 ret = SECURITY_SERVER_SUCCESS;
334 /* Create a cookie item from PID */
335 cookie_list *create_cookie_item(int pid, int sockfd, cookie_list *c_list)
338 cookie_list *added = NULL, *current = NULL;
339 char path[24], *exe = NULL;
340 char *buf = NULL, inputed, *tempptr = NULL;
341 char delim[] = ": ", *token = NULL;
342 int *permissions = NULL, perm_num = 1, cnt, i, *tempperm = NULL;
343 char *smack_label = NULL;
346 current = search_existing_cookie(pid, c_list);
349 /* There is a cookie for this process already */
351 SEC_SVR_DBG("%s", "Existing cookie found");
355 /* Read command line of the PID from proc fs */
356 exe = (char *)read_exe_path_from_proc(pid);
359 SEC_SVR_DBG("Error on reading /proc/%d/exe", pid);
364 * modified by security part
365 * - get gid from /etc/group
367 /* Read group info of the PID from proc fs - /proc/[PID]/status */
368 snprintf(path, sizeof(path), "/proc/%d/status", pid);
369 fp = fopen(path, "r");
371 /* Find the line which starts with 'Groups:' */
376 buf = (char*)malloc(sizeof(char) * 128);
379 SEC_SVR_DBG("%s", "Error on malloc()");
382 memset(buf, 0x00, 128);
385 /* get one line from /proc/[PID]/status */
389 inputed = (char)tempint;
392 else if(inputed == '\n')
397 else if((i == cnt) && (inputed != '\n'))
399 tempptr = (char*)realloc(buf, sizeof(char) * (i + 128));
402 SEC_SVR_DBG("%s", "Error on realloc()");
415 if(strncmp(buf, "Groups:", 7) == 0)
417 /* get gid from the line and insert to 'permissions' array */
418 token = strtok(buf, delim); // first string is "Groups"
419 while((token = strtok(NULL, delim)))
421 tempperm = realloc(permissions, sizeof(int) * perm_num);
424 SEC_SVR_DBG("%s", "Error on realloc()");
427 permissions = tempperm;
429 permissions[perm_num - 1] = strtoul(token, 0, 10);
432 SEC_SVR_DBG("cannot change string to integer [%s]", token);
433 ret = SECURITY_SERVER_ERROR_SERVER_ERROR;
440 /* goto out of while loop */
451 /* Each group ID is stored in each line of the file */
452 // while(fgets(permline, sizeof(permline), fp) != NULL)
454 // permissions = realloc(permissions, sizeof(int) * perm_num);
455 // if(permissions == NULL)
457 // SEC_SVR_DBG("%s", "Error on realloc()");
460 // permissions[perm_num -1] = strtoul(permline, 0, 10);
468 /* Go to last cookie from the list */
470 while(current->next != NULL)
472 current = current->next;
475 /* Create a new one and assign values */
476 added = malloc(sizeof(cookie_list));
480 ret = generate_random_cookie(added->cookie, SECURITY_SERVER_COOKIE_LEN);
481 if(ret != SECURITY_SERVER_SUCCESS)
483 SEC_SVR_DBG("Error on making random cookie: %d", ret);
489 /* Check SMACK label */
492 ret = smack_new_label_from_socket(sockfd, &smack_label);
495 SEC_SVR_DBG("Error checking peer label: %d", ret);
502 /* Check SMACK label */
505 ret = smack_new_label_from_socket(sockfd, &smack_label);
508 SEC_SVR_DBG("Error checking peer label: %d", ret);
515 added->permission_len = perm_num;
517 added->permissions = permissions;
518 added->smack_label = smack_label;
519 added->prev = current;
520 current->next = added;
531 if(added == NULL && permissions != NULL)
537 /* Check stored default cookie, if it's not exist make a new one and store it */
538 int check_stored_cookie(unsigned char *cookie, int size)
542 /* First, check the default cookie is stored */
543 fd = open(SECURITY_SERVER_DEFAULT_COOKIE_PATH, O_RDONLY);
548 SEC_SVR_DBG("Cannot open default cookie. errno=%d", errno);
549 ret = SECURITY_SERVER_ERROR_FILE_OPERATION;
550 unlink(SECURITY_SERVER_DEFAULT_COOKIE_PATH);
553 ret = generate_random_cookie(cookie, size);
555 /* Save cookie to disk */
556 fd = open(SECURITY_SERVER_DEFAULT_COOKIE_PATH, O_WRONLY | O_CREAT, 0600);
559 SEC_SVR_DBG("Cannot open default cookie errno=%d", errno);
560 ret = SECURITY_SERVER_ERROR_FILE_OPERATION;
563 ret = TEMP_FAILURE_RETRY(write(fd, cookie, size));
566 SEC_SVR_DBG("%s", "Cannot save default cookie");
567 ret = SECURITY_SERVER_ERROR_FILE_OPERATION;
572 return SECURITY_SERVER_SUCCESS;
575 ret = TEMP_FAILURE_RETRY(read(fd, cookie, size));
578 SEC_SVR_DBG("Cannot read default cookie errno=%d", errno);
579 ret = SECURITY_SERVER_ERROR_FILE_OPERATION;
582 ret = SECURITY_SERVER_SUCCESS;
589 /* Create a cookie item from PID */
591 /* Create a default cookie when security server is executed *
592 * Default cookie is for root processes that needs cookie */
593 cookie_list *create_default_cookie(void)
595 cookie_list *first = NULL;
598 first = malloc(sizeof(cookie_list));
600 ret = check_stored_cookie(first->cookie, SECURITY_SERVER_COOKIE_LEN);
601 if(ret != SECURITY_SERVER_SUCCESS)
603 SEC_SVR_DBG("Error on making random cookie: %d", ret);
608 first->permission_len = 0;
611 first->permissions = NULL;
612 first->smack_label = NULL;