After looking at the basics of Virtual File System (VFS) and how the data behaves in the client for VFS virtualized directories in the previous articles in the series, let’s finish up the discussion of VFS folders by looking at one specific – rather interesting – bug (because that’s what it must be) when it comes to fully virtualized folders and the whole concept of isolation.
As we have already seen, the purpose of marking a directory entry as fully virtualized (i.e. in override local folder –state in Sequencer-speak) is to mask anything and everything underneath it in the “real” file system. This would mask away a potentially conflicting local installation of the same application or version of the same application, which likely uses the same directory structure(s) for its installation and/or data files. So the virtual application is not able to see files from the local install, sidestepping the issue of mixing resources of two different installs or version together.
Another, secondary, benefit of using fully virtualized folders is to confine all data that the application may store on that folder during runtime; all possible changes to a fully virtualized folder will be 100% cached in App-V Client PKG and won’t be passed through to the local system. But as has been discussed, sometimes this can actually be a problem since you might want to let some type of files go to the local system, like database files that could potentially grow into too big of a size for App-V PKG to handle (around 1GB for the whole PKG file, according to Sebastian Gernert when this matter was touched in a bit different context during last App-V User Group Day)
At least that’s what the theory says to us.
The keyword in the explanation above is that applications cannot see the files from the local system when they are masked by VFS’ fully virtualized folders. But they sure can access them, as I will demonstrate in a short while!
I actually bumped into this very issue through trying to investigate the root cause of one support call that we received already in 2010, I think, whereby the custom that was using our Virtualization Encoder solution was having an interesting issue. He had a custom in-house application they were wrapping as App-V Package using our solution, but was having a problem when this application was executed on a client: it kept opening a file from one of the application’s own directories in a user’s profile, even though one of the containing folders in the path was marked as fully virtualized in a SFT package.
At first I of course assumed this may have been some very subtle bug in our package generation, but when I reproduced similar kind of package using Sequencer and tested it on a client, the behavior persisted. You see, the customer had the same folder structure in the real profile directory as was in the package, with few additions after having used the application, and the application was coded to just open certain files from certain paths. And it so happens, one of those files was the one that did not (initially) existed on the virtual environment but existed in that real profile.
What looked like an impossible situation was actually a reality: application could open a file “through” fully virtualized VFS folder as long as it knows it’s there. Granted, this may not be something that user knowingly would initiate, but it could easily happen internally in an application since most applications are programmed with the idea that they have configuration files and all sorts of application’s internal data files in certain (application-private) paths. And most applications would try to automatically open those files upon startup, since that’s, well, the whole point of having application data files!
Ok, moving in to demonstrating how this all can be seen happening in practice if I would go and try to access something that should “not be there”: at first I will concot (like oh so many times before) a yet another test package that carries fully virtualized VFS folder in it which I try to break in the client. To make it easy for you to test along, I’ll give you step by step instructions.
Preparing a package for testing
Now that our Application Virtualization Explorer (AVE) 2.3 is out, this can easily be done without any involvement of Sequencer (which speeds things up) since AVE is able to create empty sequences from scratch:
After an empty package has been initialized, let’s go and define a simple subdirectory of roaming application data (%CSIDL_APPDATA%) as normal application would likely use:
I also rename the folder to something that resembles normal application directory in AppData, after which we need the last critical piece which is changing the virtualization level into fully virtualized from the default merged that AVE creates new folders as:
Now that we have a perfect demonstration directory for our VFS testing purposes, we don’t really need to add any files to it since we are not interested in any of the files inside the package…
Lastly before saving out the package for an actual test of the VFS watertightness, let’s add application into a package that can be used for testing, Notepad, and create a shortcut for it on a desktop:
By the way, and referring to my earlier blog article on package naming here, note how that version field for a notepad.exe is by default something that we might want to clean up in a real life…
Having one fully virtualized VFS folder in a package, along with a virtual application from outside the package is enough to demonstrate the leak in isolation so we are ready to save out the package and move it over to the App-V Client machine.
Test on a App-V Client machine
Before we can actually test anything with our App-V package, we have to prepare our local file system a little bit, otherwise there would not be any point in demonstrating that we can access something from it, would there?
Since we have a folder called “AppX” in the package, we’ll create the same base folder into a roaming application data folder, together with some subfolders and files as well:
After having our test rig in place, we import the package into our App-V Client (4.6 SP1 with hotfix 3) and should see new icon on a desktop after importing, which will start local Notepad into package’s virtual environment.
After launching the Notepad, we can now browse to the AppData from File -> Open (old but useful tip: use %appdata% in the address –field, which will be resolved to the correct directory immediately after pressing enter –key over there):
Looking at the AppX subfolder, we can see it comes from the package itself and shows no signs of anything being underneath it:
However, we just happen to know about that there is in fact data under it; it’s just that it’s in local version of the same folder path. By utilizing that knowledge, we can break into local environment by explicitly entering address to the file we are interested in. This is functionally equivalent to your application internally querying Windows for the presence of some file in some absolute path, or just by trying and opening it:
And, hey presto, Notepad opens up our file that was supposed to be isolated from the application!
Interestingly enough, if we now go ahead and try “Save As” from the File –menu, Notepad is aware that there isn’t Subfolder 2, which is technically true for our virtual environment and would not let Save dialog to have that folder open:
But if we just hit regular Save, it will go through and the file is modified. Furthermore, it is not written to PKG file for the virtual package but rather the modification passes through to the local text file on a local system.
To conclude this series and to summarize the issue outlined in this article, I’m not saying that this issue will necessarily hit you as it depends on very specific conditions, but it is something to be aware of when troubleshooting packages that contain an application which has before been deployed in a traditional manner and from which would not want to re-use data from. Residues in profile directories, and other places where uninstall would not remove data, can fool virtual applications into opening files that it should not see or access.
I guess we now also know (at least partial reason) why the long-standing best practice has been not to deploy virtual applications into machines with the very same application as local installation… right? Right!