FreeBSD/usr.sbin/jail/command.c
/*
 * Make sure a mount or consolelog path is a valid absolute pathname
 * with no symlinks.
 */
Make sure a mount or consolelog path is a valid absolute pathname
with no symlinks.
Make sure a mount or consolelog path is a valid absolute pathname with no symlinks .
static int
check_path(struct cfjail *j, const char *pname, const char *path, int isfile,
    const char *umount_type)
{
	struct stat st, mpst;
	struct statfs stfs;
	char *tpath, *p;
	const char *jailpath;
	size_t jplen;
	if (path[0] != '/') {
		jail_warnx(j, "%s: %s: not an absolute pathname",
		    pname, path);
		return -1;
	}
	jailpath = string_param(j->intparams[KP_PATH]);
	if (jailpath == NULL)
		jailpath = "";
	jplen = strlen(jailpath);
	if (!strncmp(path, jailpath, jplen) && path[jplen] == '/') {
		tpath = alloca(strlen(path) + 1);
		strcpy(tpath, path);
		for (p = tpath + jplen; p != NULL; ) {
			p = strchr(p + 1, '/');
			if (p)
				*p = '\0';
			if (lstat(tpath, &st) < 0) {
				if (errno == ENOENT && isfile && !p)
					break;
				jail_warnx(j, "%s: %s: %s", pname, tpath,
				    strerror(errno));
				return -1;
			}
			if (S_ISLNK(st.st_mode)) {
				jail_warnx(j, "%s: %s is a symbolic link",
				    pname, tpath);
				return -1;
			}
			if (p)
				*p = '/';
		}
	}
	if (umount_type != NULL) {
		if (stat(path, &st) < 0 || statfs(path, &stfs) < 0) {
			jail_warnx(j, "%s: %s: %s", pname, path,
			    strerror(errno));
			return -1;
		}
		if (stat(stfs.f_mntonname, &mpst) < 0) {
			jail_warnx(j, "%s: %s: %s", pname, stfs.f_mntonname,
			    strerror(errno));
			return -1;
		}
		if (st.st_ino != mpst.st_ino) {
			jail_warnx(j, "%s: %s: not a mount point",
			    pname, path);
			return -1;
		}
		if (strcmp(stfs.f_fstypename, umount_type)) {
			jail_warnx(j, "%s: %s: not a %s mount",
			    pname, path, umount_type);
			return -1;
		}
	}
	return 0;
}
static int check_path ( struct cfjail * j , const char * pname , const char * path , int isfile , const char * umount_type ) { struct stat st , mpst ; struct statfs stfs ; char * tpath , * p ; const char * jailpath ; size_t jplen ; if ( path [ 0 ] != ' ' ) { jail_warnx ( j , " " , pname , path ) ; return -1 ; } jailpath = string_param ( j -> intparams [ KP_PATH ] ) ; if ( jailpath == NULL ) jailpath = " " ; jplen = strlen ( jailpath ) ; if ( ! strncmp ( path , jailpath , jplen ) && path [ jplen ] == ' ' ) { tpath = alloca ( strlen ( path ) + 1 ) ; strcpy ( tpath , path ) ; for ( p = tpath + jplen ; p != NULL ; ) { p = strchr ( p + 1 , ' ' ) ; if ( p ) * p = ' \0 ' ; if ( lstat ( tpath , & st ) < 0 ) { if ( errno == ENOENT && isfile && ! p ) break ; jail_warnx ( j , " " , pname , tpath , strerror ( errno ) ) ; return -1 ; } if ( S_ISLNK ( st . st_mode ) ) { jail_warnx ( j , " " , pname , tpath ) ; return -1 ; } if ( p ) * p = ' ' ; } } if ( umount_type != NULL ) { if ( stat ( path , & st ) < 0 || statfs ( path , & stfs ) < 0 ) { jail_warnx ( j , " " , pname , path , strerror ( errno ) ) ; return -1 ; } if ( stat ( stfs . f_mntonname , & mpst ) < 0 ) { jail_warnx ( j , " " , pname , stfs . f_mntonname , strerror ( errno ) ) ; return -1 ; } if ( st . st_ino != mpst . st_ino ) { jail_warnx ( j , " " , pname , path ) ; return -1 ; } if ( strcmp ( stfs . f_fstypename , umount_type ) ) { jail_warnx ( j , " " , pname , path , umount_type ) ; return -1 ; } } return 0 ; }
Make sure a mount or consolelog path is a valid absolute pathname
 with no symlinks.
Make sure a mount or consolelog path is a valid absolute pathname with no symlinks .
/*
	 * Only check for symlinks in components below the jail's path,
	 * since that's where the security risk lies.
	 */