/[path-sandbox]/trunk/sandbox_futils.c
Gentoo

Diff of /trunk/sandbox_futils.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 16 Revision 82
29 29
30#include "sandbox.h" 30#include "sandbox.h"
31#include "config.h" 31#include "config.h"
32 32
33/* BEGIN Prototypes */ 33/* BEGIN Prototypes */
34int file_security_check(char *filename); 34SB_STATIC int file_security_check(char *filename);
35/* END Prototypes */ 35/* END Prototypes */
36 36
37
38/* glibc modified getcwd() functions */ 37/* glibc modified getcwd() functions */
39char *egetcwd(char *, size_t); 38SB_STATIC char *egetcwd(char *, size_t);
40 39
41char *
42get_sandbox_path(char *argv0) 40SB_STATIC char *get_sandbox_path(char *argv0)
43{ 41{
44 char path[255]; 42 char path[255];
45 char *cwd = NULL; 43 char *cwd = NULL;
46 44
47 memset(path, 0, sizeof(path)); 45 memset(path, 0, sizeof(path));
48 /* ARGV[0] specifies full path */ 46 /* ARGV[0] specifies full path */
49 if (argv0[0] == '/') { 47 if (argv0[0] == '/') {
50 strncpy(path, argv0, sizeof(path)-1); 48 strncpy(path, argv0, sizeof(path) - 1);
51 49
52 /* ARGV[0] specifies relative path */ 50 /* ARGV[0] specifies relative path */
53 } else { 51 } else {
54 egetcwd(cwd, sizeof(path)-2); 52 egetcwd(cwd, sizeof(path) - 2);
55 snprintf(path, sizeof(path), "%s/%s", cwd, argv0); 53 snprintf(path, sizeof(path), "%s/%s", cwd, argv0);
56 if (cwd) 54 if (cwd)
57 free(cwd); 55 free(cwd);
58 cwd = NULL; 56 cwd = NULL;
59 } 57 }
60 58
61 /* Return just directory */ 59 /* Return just directory */
62 return (sb_dirname(path)); 60 return (sb_dirname(path));
63} 61}
64 62
65char *
66get_sandbox_lib(char *sb_path) 63SB_STATIC char *get_sandbox_lib(char *sb_path)
67{ 64{
68 char path[255]; 65 char path[255];
69 66
70#ifdef SB_HAVE_64BIT_ARCH 67#ifdef SB_HAVE_64BIT_ARCH
71 snprintf(path, sizeof(path), "%s", LIB_NAME); 68 snprintf(path, sizeof(path), "%s", LIB_NAME);
72#else 69#else
73 snprintf(path, sizeof(path), "%s/%s", LIBSANDBOX_PATH,LIB_NAME); 70 snprintf(path, sizeof(path), "%s/%s", LIBSANDBOX_PATH, LIB_NAME);
74 if (file_exist(path, 0) <= 0) { 71 if (file_exist(path, 0) <= 0) {
75 snprintf(path, sizeof(path), "%s%s", sb_path, LIB_NAME); 72 snprintf(path, sizeof(path), "%s%s", sb_path, LIB_NAME);
76 } 73 }
77#endif 74#endif
78 return (strdup(path)); 75 return (strdup(path));
79} 76}
80 77
81char *
82get_sandbox_pids_file(void) 78SB_STATIC char *get_sandbox_pids_file(void)
83{ 79{
84 if (0 < getenv("SANDBOX_PIDS_FILE")) { 80 if (0 < getenv("SANDBOX_PIDS_FILE")) {
85 return (strdup(getenv("SANDBOX_PIDS_FILE"))); 81 return (strdup(getenv("SANDBOX_PIDS_FILE")));
86 } 82 }
87 return (strdup(PIDS_FILE)); 83 return (strdup(PIDS_FILE));
88} 84}
89 85
90char *
91get_sandbox_rc(char *sb_path) 86SB_STATIC char *get_sandbox_rc(char *sb_path)
92{ 87{
93 char path[255]; 88 char path[255];
94 89
95 snprintf(path, sizeof(path), "%s/%s", SANDBOX_BASHRC_PATH, BASHRC_NAME); 90 snprintf(path, sizeof(path), "%s/%s", SANDBOX_BASHRC_PATH, BASHRC_NAME);
96 if (file_exist(path, 0) <= 0) { 91 if (file_exist(path, 0) <= 0) {
97 snprintf(path, sizeof(path), "%s%s", sb_path, BASHRC_NAME); 92 snprintf(path, sizeof(path), "%s%s", sb_path, BASHRC_NAME);
98 } 93 }
99 return (strdup(path)); 94 return (strdup(path));
100} 95}
101 96
102char * 97SB_STATIC char *get_sandbox_log()
103get_sandbox_log()
104{ 98{
105 char path[255]; 99 char path[255];
106 char *sandbox_log_env = NULL; 100 char *sandbox_log_env = NULL;
107 101
108 /* THIS CHUNK BREAK THINGS BY DOING THIS: 102 /* THIS CHUNK BREAK THINGS BY DOING THIS:
109 * SANDBOX_LOG=/tmp/sandbox-app-admin/superadduser-1.0.7-11063.log 103 * SANDBOX_LOG=/tmp/sandbox-app-admin/superadduser-1.0.7-11063.log
110 */ 104 */
111 105
112 sandbox_log_env = getenv(ENV_SANDBOX_LOG); 106 sandbox_log_env = getenv(ENV_SANDBOX_LOG);
113 snprintf(path, sizeof(path)-1, "%s%s%s%d%s", LOG_FILE_PREFIX, 107 snprintf(path, sizeof(path) - 1, "%s%s%s%d%s", LOG_FILE_PREFIX,
114 ( sandbox_log_env == NULL ? "" : sandbox_log_env ), 108 (sandbox_log_env == NULL ? "" : sandbox_log_env),
115 ( sandbox_log_env == NULL ? "" : "-" ), 109 (sandbox_log_env == NULL ? "" : "-"), getpid(), LOG_FILE_EXT);
116 getpid(), LOG_FILE_EXT);
117 return (strdup(path)); 110 return (strdup(path));
118} 111}
119 112
120/* Obtain base directory name. Do not allow trailing / */ 113/* Obtain base directory name. Do not allow trailing / */
121char *
122sb_dirname(const char *path) 114SB_STATIC char *sb_dirname(const char *path)
123{ 115{
124 char *ret = NULL; 116 char *ret = NULL;
125 char *ptr = NULL; 117 char *ptr = NULL;
126 int loc = 0, i; 118 int loc = 0, i;
127 int cut_len = -1; 119 int cut_len = -1;
140 loc = ptr - path; 132 loc = ptr - path;
141 133
142 /* Remove any trailing slash */ 134 /* Remove any trailing slash */
143 for (i = loc - 1; i >= 0; i--) { 135 for (i = loc - 1; i >= 0; i--) {
144 if (path[i] != '/') { 136 if (path[i] != '/') {
145 cut_len = i + 1; /* make cut_len the length of the string to keep */ 137 cut_len = i + 1; /* make cut_len the length of the string to keep */
146 break; 138 break;
147 } 139 }
148 } 140 }
149 141
150 /* It could have been just a plain /, return a 1byte 0 filled string */ 142 /* It could have been just a plain /, return a 1byte 0 filled string */
151 if (-1 == cut_len) 143 if (-1 == cut_len)
152 return (strdup("")); 144 return (strdup(""));
153 145
154 /* Allocate memory, and return the directory */ 146 /* Allocate memory, and return the directory */
155 ret = (char *) malloc((cut_len + 1) * sizeof (char)); 147 ret = (char *)malloc((cut_len + 1) * sizeof(char));
156 memcpy(ret, path, cut_len); 148 memcpy(ret, path, cut_len);
157 ret[cut_len] = 0; 149 ret[cut_len] = 0;
158 150
159 return (ret); 151 return (ret);
160} 152}
161 153
162/* 154/*
163char* dirname(const char* path) 155SB_STATIC char* dirname(const char* path)
164{ 156{
165 char* base = NULL; 157 char* base = NULL;
166 unsigned int length = 0; 158 unsigned int length = 0;
167 159
168 base = strrchr(path, '/'); 160 base = strrchr(path, '/');
182 174
183 return base; 175 return base;
184}*/ 176}*/
185 177
186/* Convert text (string) modes to integer values */ 178/* Convert text (string) modes to integer values */
187int
188file_getmode(char *mode) 179SB_STATIC int file_getmode(char *mode)
189{ 180{
190 int mde = 0; 181 int mde = 0;
191 if (0 == strcasecmp(mode, "r+")) { 182 if (0 == strcasecmp(mode, "r+")) {
192 mde = O_RDWR | O_CREAT; 183 mde = O_RDWR | O_CREAT;
193 } else if (0 == strcasecmp(mode, "w+")) { 184 } else if (0 == strcasecmp(mode, "w+")) {
205 } 196 }
206 return (mde); 197 return (mde);
207} 198}
208 199
209/* Get current position in file */ 200/* Get current position in file */
210long 201SB_STATIC long file_tell(int fp)
211file_tell(int fp)
212{ 202{
213 return (lseek(fp, 0L, SEEK_CUR)); 203 return (lseek(fp, 0L, SEEK_CUR));
214} 204}
215 205
216/* lock the file, preferrably the POSIX way */ 206/* lock the file, preferrably the POSIX way */
217int
218file_lock(int fd, int lock, char *filename) 207SB_STATIC int file_lock(int fd, int lock, char *filename)
219{ 208{
220 int err; 209 int err;
221#ifdef USE_FLOCK 210#ifdef USE_FLOCK
222 if (flock(fd, lock) < 0) { 211 if (flock(fd, lock) < 0) {
223 err = errno; 212 err = errno;
239#endif 228#endif
240 return 1; 229 return 1;
241} 230}
242 231
243/* unlock the file, preferrably the POSIX way */ 232/* unlock the file, preferrably the POSIX way */
244int 233SB_STATIC int file_unlock(int fd)
245file_unlock(int fd)
246{ 234{
247#ifdef USE_FLOCK 235#ifdef USE_FLOCK
248 if (flock(fd, LOCK_UN) < 0) { 236 if (flock(fd, LOCK_UN) < 0) {
249 perror(">>> flock file unlock"); 237 perror(">>> flock file unlock");
250 return 0; 238 return 0;
265} 253}
266 254
267/* Auto-determine from how the file was opened, what kind of lock to lock 255/* Auto-determine from how the file was opened, what kind of lock to lock
268 * the file with 256 * the file with
269 */ 257 */
270int
271file_locktype(char *mode) 258SB_STATIC int file_locktype(char *mode)
272{ 259{
273#ifdef USE_FLOCK 260#ifdef USE_FLOCK
274 if (NULL != (strchr(mode, 'w')) || (NULL != strchr(mode, '+')) 261 if (NULL != (strchr(mode, 'w')) || (NULL != strchr(mode, '+'))
275 || (NULL != strchr(mode, 'a'))) 262 || (NULL != strchr(mode, 'a')))
276 return (LOCK_EX); 263 return (LOCK_EX);
277 return (LOCK_SH); 264 return (LOCK_SH);
278#else 265#else
279 if (NULL != (strchr(mode, 'w')) || (NULL != strchr(mode, '+')) 266 if (NULL != (strchr(mode, 'w')) || (NULL != strchr(mode, '+'))
280 || (NULL != strchr(mode, 'a'))) 267 || (NULL != strchr(mode, 'a')))
281 return (F_WRLCK); 268 return (F_WRLCK);
282 return (F_RDLCK); 269 return (F_RDLCK);
283#endif 270#endif
284} 271}
285 272
286/* Use standard fopen style modes to open the specified file. Also auto-determines and 273/* Use standard fopen style modes to open the specified file. Also auto-determines and
287 * locks the file either in shared or exclusive mode depending on opening mode 274 * locks the file either in shared or exclusive mode depending on opening mode
288 */ 275 */
289int
290file_open(char *filename, char *mode, int perm_specified, ...) 276SB_STATIC int file_open(char *filename, char *mode, int perm_specified, ...)
291{ 277{
292 int fd; 278 int fd;
293 char error[250]; 279 char error[250];
294 va_list ap; 280 va_list ap;
295 int perm; 281 int perm;
296 char *group = NULL; 282 char *group = NULL;
297 struct group *group_struct; 283 struct group *group_struct;
298 284
299 file_security_check(filename); 285 file_security_check(filename);
300 286
301 if (perm_specified) { 287 if (perm_specified) {
302 va_start(ap, perm_specified); 288 va_start(ap, perm_specified);
303 perm = va_arg(ap, int); 289 perm = va_arg(ap, int);
317 perror(error); 303 perror(error);
318 } 304 }
319 } 305 }
320 if (NULL != group) { 306 if (NULL != group) {
321 group_struct = getgrnam(group); 307 group_struct = getgrnam(group);
322 if (NULL == group) { 308 if (NULL == group_struct) {
323 snprintf(error, sizeof(error), ">>> Could not get grp number: %s", group); 309 snprintf(error, sizeof(error), ">>> Could not get grp number: %s", group);
324 perror(error); 310 perror(error);
325 } else { 311 } else {
326 if (fchown(fd, -1, group_struct->gr_gid) && (0 == getuid())) { 312 if (fchown(fd, -1, group_struct->gr_gid) && (0 == getuid())) {
327 snprintf(error, sizeof(error), ">>> Could not set group: %s", filename); 313 snprintf(error, sizeof(error), ">>> Could not set group: %s", filename);
329 } 315 }
330 } 316 }
331 } 317 }
332 /* Only lock the file if opening succeeded */ 318 /* Only lock the file if opening succeeded */
333 if (-1 != fd) { 319 if (-1 != fd) {
334 if(file_security_check(filename) != 0) { 320 if (file_security_check(filename) != 0) {
335 /* Security violation occured between the last check and the */ 321 /* Security violation occured between the last check and the */
336 /* creation of the file. As SpanKY pointed out there is a race */ 322 /* creation of the file. As SpanKY pointed out there is a race */
337 /* condition here, so if there is a problem here we'll mesg and */ 323 /* condition here, so if there is a problem here we'll mesg and */
338 /* bail out to avoid it until we can work and test a better fix. */ 324 /* bail out to avoid it until we can work and test a better fix. */
339 fprintf(stderr, "\n\nSECURITY RACE CONDITION: Problem recurred after creation!\nBAILING OUT\n\n"); 325 fprintf(stderr, "\n\nSECURITY RACE CONDITION: Problem recurred after creation!\nBAILING OUT\n\n");
340 exit(127); 326 exit(127);
350 } 336 }
351 return (fd); 337 return (fd);
352} 338}
353 339
354/* Close and unlock file */ 340/* Close and unlock file */
355void 341SB_STATIC void file_close(int fd)
356file_close(int fd)
357{ 342{
358 if (-1 != fd) { 343 if (-1 != fd) {
359 file_unlock(fd); 344 file_unlock(fd);
360 close(fd); 345 close(fd);
361 } 346 }
362} 347}
363 348
364/* Return length of file */ 349/* Return length of file */
365long 350SB_STATIC long file_length(int fd)
366file_length(int fd)
367{ 351{
368 long pos, len; 352 long pos, len;
369 pos = file_tell(fd); 353 pos = file_tell(fd);
370 len = lseek(fd, 0L, SEEK_END); 354 len = lseek(fd, 0L, SEEK_END);
371 lseek(fd, pos, SEEK_SET); 355 lseek(fd, pos, SEEK_SET);
372 return (len); 356 return (len);
373} 357}
374 358
375/* Zero out file */ 359/* Zero out file */
376int
377file_truncate(int fd) 360SB_STATIC int file_truncate(int fd)
378{ 361{
379 lseek(fd, 0L, SEEK_SET); 362 lseek(fd, 0L, SEEK_SET);
380 if (ftruncate(fd, 0) < 0) { 363 if (ftruncate(fd, 0) < 0) {
381 perror(">>> file truncate"); 364 perror(">>> file truncate");
382 return 0; 365 return 0;
383 } 366 }
384 return 1; 367 return 1;
385} 368}
386 369
387/* Check to see if a file exists Return: 1 success, 0 file not found, -1 error */ 370/* Check to see if a file exists Return: 1 success, 0 file not found, -1 error */
388int
389file_exist(char *filename, int checkmode) 371SB_STATIC int file_exist(char *filename, int checkmode)
390{ 372{
391 struct stat mystat; 373 struct stat mystat;
392 374
393 /* Verify file exists and is regular file (not sym link) */ 375 /* Verify file exists and is regular file (not sym link) */
394 if (checkmode) { 376 if (checkmode) {
395 if (-1 == lstat(filename, &mystat)) { 377 if (-1 == lstat(filename, &mystat)) {
396 /* file doesn't exist */ 378 /* file doesn't exist */
397 if (ENOENT == errno) { 379 if (ENOENT == errno) {
398 return 0; 380 return 0;
399 } else { /* permission denied or other error */ 381 } else { /* permission denied or other error */
400 perror(">>> stat file"); 382 perror(">>> stat file");
401 return -1; 383 return -1;
402 } 384 }
403 } 385 }
404 if (!S_ISREG(mystat.st_mode)) 386 if (!S_ISREG(mystat.st_mode))
408 } else { 390 } else {
409 if (-1 == stat(filename, &mystat)) { 391 if (-1 == stat(filename, &mystat)) {
410 /* file does not exist */ 392 /* file does not exist */
411 if (ENOENT == errno) { 393 if (ENOENT == errno) {
412 return 0; 394 return 0;
413 } else { /* permission denied or other error */ 395 } else { /* permission denied or other error */
414 perror(">>> stat file"); 396 perror(">>> stat file");
415 return -1; 397 return -1;
416 } 398 }
417 } 399 }
418 } 400 }
419 401
420 return 1; 402 return 1;
421} 403}
422 404
423int file_security_check(char *filename) { /* 0 == fine, >0 == problem */ 405SB_STATIC int file_security_check(char *filename)
406{ /* 0 == fine, >0 == problem */
424 struct stat stat_buf; 407 struct stat stat_buf;
425 struct group *group_buf; 408 struct group *group_buf;
426 struct passwd *passwd_buf; 409 struct passwd *passwd_buf;
427 410
428 passwd_buf = getpwnam("portage"); 411 passwd_buf = getpwnam("portage");
429 group_buf = getgrnam("portage"); 412 group_buf = getgrnam("portage");
430 413
431 if((lstat(filename, &stat_buf) == -1) && (errno == ENOENT)) { 414 if ((lstat(filename, &stat_buf) == -1) && (errno == ENOENT)) {
432 /* Doesn't exist. */ 415 /* Doesn't exist. */
433 return 0; 416 return 0;
434 }
435 else { 417 } else {
436 if((stat_buf.st_nlink) > 1) { /* Security: We are handlinked... */ 418 if ((stat_buf.st_nlink) > 1) { /* Security: We are handlinked... */
437 if(unlink(filename)) { 419 if (unlink(filename)) {
438 fprintf(stderr,
439 "Unable to delete file in security violation (hardlinked): %s\n", 420 fprintf(stderr, "Unable to delete file in security violation (hardlinked): %s\n", filename);
440 filename);
441 exit(127); 421 exit(127);
442 } 422 }
443 fprintf(stderr,
444 "File in security violation (hardlinked): %s\n", 423 fprintf(stderr, "File in security violation (hardlinked): %s\n", filename);
445 filename);
446 return 1; 424 return 1;
447 }
448 else if(S_ISLNK(stat_buf.st_mode)) { /* Security: We are a symlink? */ 425 } else if (S_ISLNK(stat_buf.st_mode)) { /* Security: We are a symlink? */
449 fprintf(stderr,
450 "File in security violation (symlink): %s\n", 426 fprintf(stderr, "File in security violation (symlink): %s\n", filename);
451 filename);
452 exit(127); 427 exit(127);
453 }
454 else if(0 == S_ISREG(stat_buf.st_mode)) { /* Security: special file */ 428 } else if (0 == S_ISREG(stat_buf.st_mode)) { /* Security: special file */
455 fprintf(stderr,
456 "File in security violation (not regular): %s\n", 429 fprintf(stderr, "File in security violation (not regular): %s\n", filename);
457 filename);
458 exit(127); 430 exit(127);
459 }
460 else if(stat_buf.st_mode & S_IWOTH) { /* Security: We are o+w? */ 431 } else if (stat_buf.st_mode & S_IWOTH) { /* Security: We are o+w? */
461 if(unlink(filename)) { 432 if (unlink(filename)) {
462 fprintf(stderr,
463 "Unable to delete file in security violation (world write): %s\n", 433 fprintf(stderr, "Unable to delete file in security violation (world write): %s\n", filename);
464 filename);
465 exit(127); 434 exit(127);
466 } 435 }
467 fprintf(stderr,
468 "File in security violation (world write): %s\n", 436 fprintf(stderr, "File in security violation (world write): %s\n", filename);
469 filename);
470 return 1; 437 return 1;
471 } 438 } else
472 else if( 439 if (!((stat_buf.st_uid == 0) || (stat_buf.st_uid == getuid()) ||
473 !((stat_buf.st_uid == 0) || (stat_buf.st_uid == getuid()) || ((passwd_buf!=NULL) && (stat_buf.st_uid == passwd_buf->pw_uid))) || 440 ((passwd_buf != NULL) && (stat_buf.st_uid == passwd_buf->pw_uid))) ||
474 !((stat_buf.st_gid == 0) || (stat_buf.st_gid == getgid()) || ((group_buf !=NULL) && (stat_buf.st_gid == group_buf->gr_gid))) 441 !((stat_buf.st_gid == 0) || (stat_buf.st_gid == getgid()) ||
442 ((group_buf != NULL) && (stat_buf.st_gid == group_buf->gr_gid)))) {
475 ) { /* Security: Owner/Group isn't right. */ 443 /* Security: Owner/Group isn't right. */
476 444
477 /* uid = 0 or myuid or portage */ 445 /* uid = 0 or myuid or portage */
478 /* gid = 0 or mygid or portage */ 446 /* gid = 0 or mygid or portage */
479 447
480 if(0) { 448 if (0) {
481 fprintf(stderr, "--1: %d,%d,%d,%d\n--2: %d,%d,%d,%d\n", 449 fprintf(stderr, "--1: %d,%d,%d,%d\n--2: %d,%d,%d,%d\n",
482
483 (stat_buf.st_uid == 0), 450 (stat_buf.st_uid == 0),
484 (stat_buf.st_uid == getuid()), 451 (stat_buf.st_uid == getuid()),
485 (passwd_buf!=NULL), 452 (passwd_buf != NULL),
486 (passwd_buf!=NULL)? (stat_buf.st_uid == passwd_buf->pw_uid) : -1, 453 (passwd_buf != NULL) ? (stat_buf.st_uid == passwd_buf->pw_uid) : -1,
487
488 (stat_buf.st_gid == 0), 454 (stat_buf.st_gid == 0),
489 (stat_buf.st_gid == getgid()), 455 (stat_buf.st_gid == getgid()),
490 (group_buf !=NULL), 456 (group_buf != NULL),
491 (group_buf !=NULL)? (stat_buf.st_gid == group_buf->gr_gid) : -1); 457 (group_buf != NULL) ? (stat_buf.st_gid == group_buf->gr_gid) : -1);
492 }
493 458 }
459
494 /* manpage: "The return value may point to static area" */ 460 /* manpage: "The return value may point to static area" */
495 /* DO NOT ACTUALLY FREE THIS... It'll segfault. */ 461 /* DO NOT ACTUALLY FREE THIS... It'll segfault. */
496 /* if(passwd_buf != NULL) { free(passwd_buf); } */ 462 /* if(passwd_buf != NULL) { free(passwd_buf); } */
497 /* if(group_buf != NULL) { free(group_buf); } */ 463 /* if(group_buf != NULL) { free(group_buf); } */
498 464
499 if(unlink(filename)) { 465 if (unlink(filename)) {
500 fprintf(stderr,
501 "Unable to delete file in security violation (bad owner/group): %s\n", 466 fprintf(stderr, "Unable to delete file in security violation (bad owner/group): %s\n", filename);
502 filename);
503 exit(127); 467 exit(127);
504 } 468 }
505 fprintf(stderr,
506 "File in security violation (bad owner/group): %s\n", 469 fprintf(stderr, "File in security violation (bad owner/group): %s\n", filename);
507 filename);
508 return 1; 470 return 1;
509 } 471 }
510 } /* Stat */ 472 } /* Stat */
511 return 0; 473 return 0;
512} 474}
513 475
514// vim:expandtab noai:cindent ai 476// vim:noexpandtab noai:cindent ai

Legend:
Removed from v.16  
changed lines
  Added in v.82

  ViewVC Help
Powered by ViewVC 1.1.20