Permalink
Browse files

* TempFileCollection.cs: Bring in changes from HEAD for serialization

       security fix:
       * r51229: Added a call to GC.SuppressFinalize in Dispose.
       * r52181: Changed BasePath property to use Path.
       GetTempPath (Environment check) and added the PathDiscovery check on
       the combined result. Fixed TempDir so it's value never change (i.e.
       imply that it doesn't need any permissions). Fixed SyncRoot to always
       return null.
       * r57836: Implement explicitly some interface methods to get rid of
       the "!" errors on CorCompare.
       * r60253: Make sure generated file names are unique. Fixes bug #76125
       and #78230.
       * r65441: Create files in a temporary subdirectory, for security reasons.


svn path=/branches/mono-1-1-4/mcs/; revision=66300
  • Loading branch information...
1 parent 01df40f commit b27152cb9d5942cbe886629f6f127fe6d1941930 Wade Berrier committed Oct 5, 2006
@@ -1,3 +1,19 @@
+2006-10-05 Wade Berrier <wberrier@novell.com>
+
+ * TempFileCollection.cs: Bring in changes from HEAD for serialization
+ security fix:
+ * r51229: Added a call to GC.SuppressFinalize in Dispose.
+ * r52181: Changed BasePath property to use Path.
+ GetTempPath (Environment check) and added the PathDiscovery check on
+ the combined result. Fixed TempDir so it's value never change (i.e.
+ imply that it doesn't need any permissions). Fixed SyncRoot to always
+ return null.
+ * r57836: Implement explicitly some interface methods to get rid of
+ the "!" errors on CorCompare.
+ * r60253: Make sure generated file names are unique. Fixes bug #76125
+ and #78230.
+ * r65441: Create files in a temporary subdirectory, for security reasons.
+
2005-01-27 LLuis Sanchez Gual <lluis@novell.com>
* CodeGenerator.cs: Write 'f' suffix for float constants.
@@ -5,8 +5,7 @@
// Dick Porter (dick@ximian.com)
//
// (C) Copyright 2003 Ximian, Inc.
-//
-
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
@@ -28,54 +27,124 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System.IO;
using System.Collections;
+using System.IO;
+using System.Security;
+using System.Security.Permissions;
+using System.Runtime.InteropServices;
-namespace System.CodeDom.Compiler
-{
+namespace System.CodeDom.Compiler {
+
+#if NET_2_0
+ [Serializable]
+#endif
+ [PermissionSet (SecurityAction.LinkDemand, Unrestricted = true)]
public class TempFileCollection:ICollection, IEnumerable, IDisposable
{
Hashtable filehash;
string tempdir;
bool keepfiles;
string basepath;
Random rnd;
+ string ownTempDir;
- public TempFileCollection(): this(null, false)
+ public TempFileCollection ()
+ : this (String.Empty, false)
{
}
- public TempFileCollection(string tempDir): this(tempDir, false)
+ public TempFileCollection(string tempDir)
+ : this (tempDir, false)
{
}
public TempFileCollection(string tempDir, bool keepFiles)
{
filehash=new Hashtable();
- tempdir=tempDir;
+ tempdir = (tempDir == null) ? String.Empty : tempDir;
keepfiles=keepFiles;
}
public string BasePath
{
get {
if(basepath==null) {
- if (tempdir==null) {
- /* Get the system temp dir */
- MonoIO.GetTempPath(out tempdir);
- }
-
+
if (rnd == null)
rnd = new Random ();
- string random = rnd.Next (10000,99999).ToString ();
- basepath = Path.Combine (tempdir, random);
+ // note: this property *cannot* change TempDir property
+ string temp = tempdir;
+ if (temp.Length == 0)
+ temp = GetOwnTempDir ();
+
+ // Create a temporary file at the target directory. This ensures
+ // that the generated file name is unique.
+ FileStream f = null;
+ do {
+ int num = rnd.Next ();
+ num++;
+ basepath = Path.Combine (temp, num.ToString("x"));
+ string path = basepath + ".tmp";
+
+ try {
+ f = new FileStream (path, FileMode.CreateNew);
+ }
+ catch (System.IO.IOException) {
+ f = null;
+ continue;
+ }
+ catch {
+ // avoid endless loop
+ throw;
+ }
+ } while (f == null);
+
+ f.Close ();
+
+ // and you must have discovery access to the combined path
+ // note: the cache behaviour is tested in the CAS tests
+ if (SecurityManager.SecurityEnabled) {
+ new FileIOPermission (FileIOPermissionAccess.PathDiscovery, basepath).Demand ();
+ }
}
return(basepath);
}
}
+
+ string GetOwnTempDir ()
+ {
+ if (ownTempDir != null)
+ return ownTempDir;
+
+ // this call ensure the Environment permissions check
+ string basedir = Path.GetTempPath ();
+
+ // Create a subdirectory with the correct user permissions
+ int res = -1;
+ do {
+ int num = rnd.Next ();
+ num++;
+ ownTempDir = Path.Combine (basedir, num.ToString("x"));
+ if (Directory.Exists (ownTempDir))
+ continue;
+ res = mkdir (ownTempDir, 0x1c0);
+ if (res != 0) {
+ if (!Directory.Exists (ownTempDir))
+ throw new IOException ();
+ // Somebody already created the dir, keep trying
+ }
+ } while (res != 0);
+ return ownTempDir;
+ }
+ int ICollection.Count {
+ get {
+ return filehash.Count;
+ }
+ }
+
public int Count
{
get {
@@ -96,11 +165,9 @@ public bool KeepFiles
public string TempDir
{
get {
- if(tempdir==null) {
- return(String.Empty);
- } else {
- return(tempdir);
- }
+ // note: we only return what we were supplied so there
+ // is no permission protecting this information
+ return tempdir;
}
}
@@ -133,7 +200,7 @@ void ICollection.CopyTo(Array array, int start)
object ICollection.SyncRoot {
get {
- return filehash.SyncRoot;
+ return null;
}
}
@@ -150,17 +217,33 @@ void IDisposable.Dispose()
public void Delete()
{
- string[] filenames=new string[filehash.Count];
- filehash.Keys.CopyTo(filenames, 0);
+ bool allDeleted = true;
+ string[] filenames = new string[filehash.Count];
+ filehash.Keys.CopyTo (filenames, 0);
foreach(string file in filenames) {
if((bool)filehash[file]==false) {
File.Delete(file);
filehash.Remove(file);
- }
+ } else
+ allDeleted = false;
+ }
+ if (basepath != null) {
+ string tmpFile = basepath + ".tmp";
+ File.Delete (tmpFile);
+ basepath = null;
+ }
+ if (allDeleted && ownTempDir != null) {
+ Directory.Delete (ownTempDir, true);
+ ownTempDir = null;
}
}
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return(filehash.Keys.GetEnumerator());
+ }
+
public IEnumerator GetEnumerator()
{
return(filehash.Keys.GetEnumerator());
@@ -169,12 +252,16 @@ public IEnumerator GetEnumerator()
protected virtual void Dispose(bool disposing)
{
Delete();
+ if (disposing) {
+ GC.SuppressFinalize (true);
+ }
}
~TempFileCollection()
{
Dispose(false);
}
+ [DllImport ("libc")] private static extern int mkdir (string olpath, uint mode);
}
}

0 comments on commit b27152c

Please sign in to comment.