static void _get_sb_log(char *path, const char *env, const char *prefix)
{
	char *sandbox_log_env = NULL;

	save_errno();

	sandbox_log_env = getenv(env);

	if (sandbox_log_env && is_env_on(ENV_SANDBOX_TESTING)) {
		/* When testing, just use what the env says to */
		strncpy(path, sandbox_log_env, SB_PATH_MAX);
	} else {
		/* THIS CHUNK BREAK THINGS BY DOING THIS:
		 * SANDBOX_LOG=/tmp/sandbox-app-admin/superadduser-1.0.7-11063.log
		 */
		if ((NULL != sandbox_log_env) &&
		    (NULL != strchr(sandbox_log_env, '/')))
		    sandbox_log_env = NULL;

		snprintf(path, SB_PATH_MAX, "%s%s%s%s%d%s",
			SANDBOX_LOG_LOCATION, prefix,
			(sandbox_log_env == NULL ? "" : sandbox_log_env),
			(sandbox_log_env == NULL ? "" : "-"),
			getpid(), LOG_FILE_EXT);
	}

	restore_errno();
}
Esempio n. 2
0
static couchstore_error_t couch_advise(couchstore_error_info_t *errinfo,
                                       couch_file_handle handle,
                                       cs_off_t offset,
                                       cs_off_t len,
                                       couchstore_file_advice_t advice)
{
#ifdef POSIX_FADV_NORMAL
    int fd = handle_to_fd(handle);
    int error = posix_fadvise(fd, offset, len, (int) advice);
    if (error != 0) {
        save_errno(errinfo);
    }
    switch(error) {
        case EINVAL:
        case ESPIPE:
            return COUCHSTORE_ERROR_INVALID_ARGUMENTS;
            break;
        case EBADF:
            return COUCHSTORE_ERROR_OPEN_FILE;
            break;
    }
#else
    (void) handle; (void)offset; (void)len; (void)advice;
    (void)errinfo;
#endif
    return COUCHSTORE_SUCCESS;
}
Esempio n. 3
0
static inline bool PRE_CHECK_FUNC(WRAPPER_NAME)(_WRAPPER_ARGS_PROTO)
{
    if (!(flags & O_CREAT)) {
        /* If we're not trying to create, fail normally if
         * file does not stat
         */
#if USE_AT
        if (dirfd == AT_FDCWD || pathname[0] == '/')
#endif
#undef USE_AT
        {
            struct stat st;
            save_errno();
            if (-1 == stat(pathname, &st)) {
                if (is_env_on(ENV_SANDBOX_DEBUG))
                    SB_EINFO("EARLY FAIL", "  %s(%s): %s\n",
                             STRING_NAME, pathname, strerror(errno));
                return false;
            }
            restore_errno();
        }
    }

    return true;
}
Esempio n. 4
0
static inline bool sb_unlinkat_pre_check(WRAPPER_ARGS_PROTO)
{
	char canonic[SB_PATH_MAX];

	save_errno();

	if (-1 == canonicalize(pathname, canonic))
		/* see comments in check_syscall() */
		if (ENAMETOOLONG != errno)
			goto error;

	/* XXX: Hack to make sure sandboxed process cannot remove
	 * a device node, bug #79836. */
	if (0 == strcmp(canonic, "/dev/null") ||
	    0 == strcmp(canonic, "/dev/zero"))
	{
		errno = EACCES;
		goto error;
	}

	restore_errno();

	return true;

 error:
	if (is_env_on(ENV_SANDBOX_DEBUG))
		SB_EINFO("EARLY FAIL", "  %s(%s): %s\n",
			STRING_NAME, pathname, strerror(errno));
	return false;
}
Esempio n. 5
0
/*Initialization of group*/
void buxtond_set_group(char *group, char *layer)
{
	client_connection();
	save_errno();
	if(_layer){
		free(_layer);
	}
	if(_group){
		free(_group);
	}
	_layer = strdup(layer);
	if(!_layer){
		printf("Layer assignment failed. Aborting operation.\n");
		return;
	}
	_group = strdup(group);
	if(!_group){
		printf("Group assignment failed. Aborting operation.\n");
		return;
	}
	BuxtonKey g = buxton_key_create(_group, NULL, _layer, STRING);
	int status;
	if (buxton_create_group(client, g, cg_cb, &status, true)){
		printf("Create group call failed.\n");
	} else {
		printf("Switched to group: %s, layer: %s.\n", buxton_key_get_group(g), buxton_key_get_layer(g));
		errno = saved_errno;
	}
	buxton_key_free(g);
}
bool sb_unlinkat_pre_check(const char *func, const char *pathname, int dirfd)
{
	char canonic[SB_PATH_MAX];

	save_errno();

	/* XXX: need to check pathname with dirfd */
	if (-1 == canonicalize(pathname, canonic))
		/* see comments in check_syscall() */
		if (ENAMETOOLONG != errno)
			goto error;

	/* XXX: Hack to make sure sandboxed process cannot remove
	 * a device node, bug #79836. */
	if (0 == strcmp(canonic, "/dev/null") ||
	    0 == strcmp(canonic, "/dev/zero"))
	{
		errno = EACCES;
		goto error;
	}

	restore_errno();

	return true;

 error:
	if (is_env_on(ENV_SANDBOX_DEBUG))
		SB_EINFO("EARLY FAIL", "  %s(%s): %s\n",
			func, pathname, strerror(errno));
	return false;
}
Esempio n. 7
0
bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
{
	char canonic[SB_PATH_MAX];
	char dirfd_path[SB_PATH_MAX];

	save_errno();

	/* Expand the dirfd path first */
	switch (resolve_dirfd_path(dirfd, pathname, dirfd_path, sizeof(dirfd_path))) {
		case -1:
			sb_debug_dyn("EARLY FAIL: %s(%s) @ resolve_dirfd_path: %s\n",
				func, pathname, strerror(errno));
			return false;
		case 0:
			pathname = dirfd_path;
			break;
	}

	/* Then break down any relative/symlink paths */
	if (-1 == canonicalize(pathname, canonic))
		/* see comments in check_syscall() */
		if (ENAMETOOLONG != errno) {
			sb_debug_dyn("EARLY FAIL: %s(%s) @ canonicalize: %s\n",
				func, pathname, strerror(errno));
			return false;
		}

	/* XXX: Hack to prevent errors if the directory exist, and are
	 * not writable - we rather return EEXIST than fail.  This can
	 * occur if doing something like `mkdir -p /`.  We certainly do
	 * not want to pass this attempt up to the higher levels as those
	 * will trigger a sandbox violation.
	 */
	struct stat st;
	if (0 == lstat(canonic, &st)) {
		int new_errno;
		sb_debug_dyn("EARLY FAIL: %s(%s[%s]) @ lstat: %s\n",
			func, pathname, canonic, strerror(errno));

		new_errno = EEXIST;

		/* Hmm, is this a broken symlink we're trying to extend ? */
		if (S_ISLNK(st.st_mode) && stat(pathname, &st) != 0) {
			/* XXX: This awful hack should probably be turned into a
			 * common func that does a better job.  For now, we have
			 * enough crap to catch gnulib tests #297026.
			 */
			char *parent = strrchr(pathname, '/');
			if (parent && (strcmp(parent, "/.") == 0 || strcmp(parent, "/..") == 0))
				new_errno = ENOENT;
		}

		errno = new_errno;
		return false;
	}

	restore_errno();

	return true;
}
bool sb_mkdirat_pre_check(const char *func, const char *pathname, int dirfd)
{
	char canonic[SB_PATH_MAX];

	save_errno();

	/* XXX: need to check pathname with dirfd */
	if (-1 == canonicalize(pathname, canonic))
		/* see comments in check_syscall() */
		if (ENAMETOOLONG != errno) {
			if (is_env_on(ENV_SANDBOX_DEBUG))
				SB_EINFO("EARLY FAIL", "  %s(%s) @ canonicalize: %s\n",
					func, pathname, strerror(errno));
			return false;
		}

	/* XXX: Hack to prevent errors if the directory exist, and are
	 * not writable - we rather return EEXIST than fail.  This can
	 * occur if doing something like `mkdir -p /`.  We certainly do
	 * not want to pass this attempt up to the higher levels as those
	 * will trigger a sandbox violation.
	 */
	struct stat st;
	if (0 == lstat(canonic, &st)) {
		if (is_env_on(ENV_SANDBOX_DEBUG))
			SB_EINFO("EARLY FAIL", "  %s(%s[%s]) @ lstat: %s\n",
				func, pathname, canonic, strerror(errno));
		errno = EEXIST;
		return false;
	}

	restore_errno();

	return true;
}
Esempio n. 9
0
static cs_off_t couch_goto_eof(couchstore_error_info_t *errinfo,
                               couch_file_handle handle)
{
    int fd = handle_to_fd(handle);
    cs_off_t rv = lseek(fd, 0, SEEK_END);
    if (rv < 0) {
        save_errno(errinfo);
    }
    return rv;
}
Esempio n. 10
0
static void load_libc_handle(void)
{
	save_errno();	/* #260765 */
	libc_handle = dlopen(LIBC_VERSION, RTLD_LAZY);
	restore_errno();

	if (!libc_handle) {
		fprintf(stderr, "libsandbox:  Can't dlopen libc: %s\n",
			dlerror());
		exit(EXIT_FAILURE);
	}
}
char *get_sandbox_conf(void)
{
	char *ret = SANDBOX_CONF_FILE;
	save_errno();
	if (is_env_on(ENV_SANDBOX_TESTING)) {
		char *abs = getenv("abs_top_srcdir");
		ret = xmalloc(strlen(abs) + strlen(LOCAL_SANDBOX_CONF_FILE) + 1);
		sprintf(ret, "%s%s", abs, LOCAL_SANDBOX_CONF_FILE);
	}
	restore_errno();
	return ret;
}
Esempio n. 12
0
static couchstore_error_t couch_sync(couchstore_error_info_t *errinfo,
                                     couch_file_handle handle)
{
    int fd = handle_to_fd(handle);
    int rv;
    do {
        rv = fdatasync(fd);
    } while (rv == -1 && errno == EINTR);

    if (rv == -1) {
        save_errno(errinfo);
        return COUCHSTORE_ERROR_WRITE;
    }

    return COUCHSTORE_SUCCESS;
}
Esempio n. 13
0
static void couch_close(couchstore_error_info_t *errinfo,
                        couch_file_handle handle)
{
    int fd = handle_to_fd(handle);
    int rv = 0;

    if (fd != -1) {
        do {
            assert(fd >= 3);
            rv = close(fd);
        } while (rv == -1 && errno == EINTR);
    }
    if (rv < 0) {
        save_errno(errinfo);
    }
}
bool sb_fopen_pre_check(const char *func, const char *pathname, const char *mode)
{
	if ((NULL != mode) && (mode[0] == 'r')) {
		save_errno();

		/* If we're trying to read, fail normally if file does not stat */
		struct stat st;
		if (-1 == stat(pathname, &st)) {
			if (is_env_on(ENV_SANDBOX_DEBUG))
				SB_EINFO("EARLY FAIL", "  %s(%s): %s\n",
					func, pathname, strerror(errno));
			return false;
		}

		restore_errno();
	}

	return true;
}
Esempio n. 15
0
int u_log_write_ex(int fac, int lev, int flags, int err, const char* file, 
    int line, const char *func, const char* fmt, ...)
{
    va_list ap;
    err_type savederr;
    int rc;
    char msg[U_MAX_LOG_LENGTH], strerr[STRERR_BUFSZ], errmsg[STRERR_BUFSZ];

    save_errno(savederr);

    /* build the message to send to the log system */
    va_start(ap, fmt); 
    rc = vsnprintf(msg, U_MAX_LOG_LENGTH, fmt, ap);
    va_end(ap);

    if(rc >= U_MAX_LOG_LENGTH)
        goto err; /* message too long */

    /* init empty strings */
    errmsg[0] = strerr[0] = 0;

    if(err)
    {
        u_strerror_r(err, strerr, sizeof(strerr));
        snprintf(errmsg, sizeof(errmsg), "[errno: %d, %s]", err, strerr);
        errmsg[sizeof(errmsg) - 1] = 0; /* paranoid set */
    } 

    /* ok, send the msg to the logger */
    if(flags & LOG_WRITE_FLAG_CTX)
        u_log(fac, lev, "[%s][%d:%s:%d:%s] %s %s", 
               u_log_label(lev), getpid(), file, line, func, msg, errmsg);
    else
        u_log(fac, lev, "[%s][%d:::] %s %s", 
               u_log_label(lev), getpid(), msg, errmsg);

    restore_errno(savederr);
    return 0;
err:
    restore_errno(savederr);
    return ~0;
}
Esempio n. 16
0
int u_console_write_ex(int err, const char* file, int line, 
    const char *func, const char* fmt, ...)
{
    err_type savederr;
    va_list ap;
    int rc;
    char strerr[STRERR_BUFSZ], errmsg[STRERR_BUFSZ];

    /* when writing to console the following parameters are not used */
    file = NULL, line = 0, func = NULL;

    save_errno(savederr);

    /* build the message to send to the log system */
    va_start(ap, fmt); 

    /* write the message to the standard error */
    rc = vfprintf(stderr, fmt, ap);

    va_end(ap);

    if(rc < 0)
        goto err;

    /* init empty strings */
    errmsg[0] = strerr[0] = 0;

    if(err)
    {
        u_strerror_r(err, strerr, sizeof(strerr));
        snprintf(errmsg, sizeof(errmsg), "[errno: %d, %s]", err, strerr);
        errmsg[sizeof(errmsg) - 1] = 0; /* paranoid set */
        fprintf(stderr, " %s\n", errmsg);
    } else
        fprintf(stderr, "\n");

    restore_errno(savederr);
    return 0;
err:
    restore_errno(savederr);
    return ~0;
}
Esempio n. 17
0
static ssize_t couch_pwrite(couchstore_error_info_t *errinfo,
                            couch_file_handle handle,
                            const void *buf,
                            size_t nbyte,
                            cs_off_t offset)
{
#ifdef LOG_IO
    fprintf(stderr, "PWRITE %8llx -- %8llx  (%6.1f kbytes)\n", offset, offset+nbyte, nbyte/1024.0);
#endif
    int fd = handle_to_fd(handle);
    ssize_t rv;
    do {
        rv = pwrite(fd, buf, nbyte, offset);
    } while (rv == -1 && errno == EINTR);

    if (rv < 0) {
        save_errno(errinfo);
        return (ssize_t) COUCHSTORE_ERROR_WRITE;
    }
    return rv;
}
Esempio n. 18
0
void buxtond_set_bool(char *key, bool value)
{
	/*make sure client connection is open*/
	client_connection();
	/*create key*/
	BuxtonKey _key = buxton_key_create(_group, strdup(key), _layer, BOOLEAN);
	/*Return value and status*/
	struct vstatus ret;
	ret.type = BOOLEAN;
	ret.bval = value;
	save_errno();
	if(buxton_set_value(client, _key, &value, bs_cb, &ret, true)){
		printf("Set bool call failed.\n");
	}
	if (!ret.status){
		errno = EACCES;
	} else {
		errno = saved_errno;
	}
	buxton_key_free(_key);
}
Esempio n. 19
0
bool buxtond_get_bool(char *key)
{
	/*make sure client connection is open*/
	client_connection();
	/*create key*/
	BuxtonKey _key = buxton_key_create(_group, strdup(key), _layer, BOOLEAN);
	/*return value*/
	struct vstatus ret;
	ret.type = BOOLEAN;
	save_errno();
	/*get value*/
	if (buxton_get_value(client, _key, bgb_cb, &ret, true)){
		printf("Get bool call failed.\n");
	}
	if (!ret.status){
		errno = EACCES;
	} else {
		errno = saved_errno;
	}
	buxton_key_free(_key);
	return ret.bval;
}
Esempio n. 20
0
static void *get_dlsym(const char *symname, const char *symver)
{
	void *symaddr = NULL;

#if defined(USE_RTLD_NEXT)
	libc_handle = RTLD_NEXT;
#endif

	/* Checking for -1UL is significant on hardened!
	 * USE_RTLD_NEXT returns it as a sign of being unusable.
	 * However using !x or NULL checks does NOT pick it up!
	 * That is also why we need to save/restore errno #260765.
	 */
#define INVALID_LIBC_HANDLE(x) (!x || NULL == x || (void *)-1UL == x)
	if (INVALID_LIBC_HANDLE(libc_handle)) {
		save_errno();
		libc_handle = dlopen(LIBC_VERSION, RTLD_LAZY);
		restore_errno();
		if (INVALID_LIBC_HANDLE(libc_handle)) {
			fprintf(stderr, "libsandbox:  Can't dlopen libc: %s\n",
				dlerror());
			exit(EXIT_FAILURE);
		}
	}
#undef INVALID_LIBC_HANDLE

	if (NULL == symver)
		symaddr = dlsym(libc_handle, symname);
	else
		symaddr = dlvsym(libc_handle, symname, symver);

	if (!symaddr) {
		fprintf(stderr, "libsandbox:  Can't resolve %s: %s\n",
			symname, dlerror());
		exit(EXIT_FAILURE);
	}

	return symaddr;
}
Esempio n. 21
0
static int
add_db_file(pesigcheck_context *ctx, db_specifier which, const char *dbfile,
	    db_f_type type)
{
	dblist *db = calloc(1, sizeof (dblist));

	if (!db)
		return -1;

	db->type = type;
	db->fd = open(dbfile, O_RDONLY);
	if (db->fd < 0) {
		save_errno(free(db));
		return -1;
	}

	char *path = strdup(dbfile);
	if (!path) {
		save_errno(close(db->fd);
			   free(db));
		return -1;
	}
Esempio n. 22
0
static couchstore_error_t couch_open(couchstore_error_info_t *errinfo,
                                     couch_file_handle* handle,
                                     const char *path,
                                     int oflag)
{
    int fd;
    do {
        fd = open(path, oflag | O_LARGEFILE, 0666);
    } while (fd == -1 && errno == EINTR);

    if (fd < 0) {
        save_errno(errinfo);
        if (errno == ENOENT) {
            return COUCHSTORE_ERROR_NO_SUCH_FILE;
        } else {
            return COUCHSTORE_ERROR_OPEN_FILE;
        }
    }
    /* Tell the caller about the new handle (file descriptor) */
    *handle = fd_to_handle(fd);
    return COUCHSTORE_SUCCESS;
}
Esempio n. 23
0
void sb_efunc(const char *color, const char *hilight, const char *format, ...)
{
    save_errno();

    int fd = STDERR_FILENO;

    if (!init_color) {
        nocolor = is_env_on(ENV_NOCOLOR);
        init_color = true;
    }

    if (!nocolor)
        sb_fdprintf(fd, "%s%s%s", color, hilight, COLOR_NORMAL);
    else
        sb_fdprintf(fd, "%s", hilight);

    va_list args;
    va_start(args, format);
    sb_vfdprintf(fd, format, args);
    va_end(args);

    restore_errno();
}
Esempio n. 24
0
void buxtond_set_int32(char *key, int32_t value)
{
	/*make sure client connection is open*/
	client_connection();
	/*check if a key has been created*/
	/*create key */
	BuxtonKey _key = buxton_key_create(_group, strdup(key), _layer, INT32);
	/*Return value and status*/
	struct vstatus ret;
	ret.type = INT32;
	ret.i32val = value;
	save_errno();
	/*call buxton_set_value for type INT32*/
	if (buxton_set_value(client, _key, &value, bs_cb, &ret, true)){
		printf("Set int32_t call failed.\n");
		return;
	}
	if (!ret.status){
		errno = EACCES;
	} else {
		errno = saved_errno;
	}
	buxton_key_free(_key);
}