Пример #1
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;
}
Пример #2
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;
}
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;
}
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;
}
Пример #5
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;
}
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();
}
Пример #7
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;
}
Пример #8
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;
}
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;
}
Пример #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);
	}
}
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;
}
Пример #12
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;
}
Пример #13
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();
}