/[path-sandbox]/trunk/libsbutil/get_sandbox_lib.c
Gentoo

Contents of /trunk/libsbutil/get_sandbox_lib.c

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

  ViewVC Help
Powered by ViewVC 1.1.20