diff options
| author | 2013-03-25 14:05:47 -0700 | |
|---|---|---|
| committer | 2013-03-25 14:05:47 -0700 | |
| commit | 7b3ac9add80fde8e36201e7c2e05a3da10c44cec (patch) | |
| tree | fc44ee2fdf63bbf598a02361bb7cebd8589eb3cc | |
| parent | bb2aa63be4a9328403a4daa2f93b42a4a7b0b65d (diff) | |
| parent | 0cb27e28071af59000198c8588c588a2e63cc0a3 (diff) | |
am 0cb27e28: Validate restored file paths against their nominal domain
* commit '0cb27e28071af59000198c8588c588a2e63cc0a3':
  Validate restored file paths against their nominal domain
| -rw-r--r-- | core/java/android/app/backup/BackupAgent.java | 28 | 
1 files changed, 19 insertions, 9 deletions
| diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index 9ad33a5a4105..0e835ed9f5b3 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -440,21 +440,31 @@ public abstract class BackupAgent extends ContextWrapper {              basePath = getCacheDir().getCanonicalPath();          } else {              // Not a supported location -            Log.i(TAG, "Data restored from non-app domain " + domain + ", ignoring"); +            Log.i(TAG, "Unrecognized domain " + domain);          }          // Now that we've figured out where the data goes, send it on its way          if (basePath != null) { +            // Canonicalize the nominal path and verify that it lies within the stated domain              File outFile = new File(basePath, path); -            if (DEBUG) Log.i(TAG, "[" + domain + " : " + path + "] mapped to " + outFile.getPath()); -            onRestoreFile(data, size, outFile, type, mode, mtime); -        } else { -            // Not a supported output location?  We need to consume the data -            // anyway, so just use the default "copy the data out" implementation -            // with a null destination. -            if (DEBUG) Log.i(TAG, "[ skipping data from unsupported domain " + domain + "]"); -            FullBackup.restoreFile(data, size, type, mode, mtime, null); +            String outPath = outFile.getCanonicalPath(); +            if (outPath.startsWith(basePath + File.separatorChar)) { +                if (DEBUG) Log.i(TAG, "[" + domain + " : " + path + "] mapped to " + outPath); +                onRestoreFile(data, size, outFile, type, mode, mtime); +                return; +            } else { +                // Attempt to restore to a path outside the file's nominal domain. +                if (DEBUG) { +                    Log.e(TAG, "Cross-domain restore attempt: " + outPath); +                } +            }          } + +        // Not a supported output location, or bad path:  we need to consume the data +        // anyway, so just use the default "copy the data out" implementation +        // with a null destination. +        if (DEBUG) Log.i(TAG, "[ skipping file " + path + "]"); +        FullBackup.restoreFile(data, size, type, mode, mtime, null);      }      // ----- Core implementation ----- |