88import attr
99import py
1010
11- from .pathlib import ensure_reset_dir
1211from .pathlib import LOCK_TIMEOUT
1312from .pathlib import make_numbered_dir
1413from .pathlib import make_numbered_dir_with_cleanup
14+ from .pathlib import rm_rf
1515from _pytest .compat import final
1616from _pytest .config import Config
1717from _pytest .deprecated import check_ispytest
@@ -90,20 +90,22 @@ def mktemp(self, basename: str, numbered: bool = True) -> Path:
9090 basename = self ._ensure_relative_to_basetemp (basename )
9191 if not numbered :
9292 p = self .getbasetemp ().joinpath (basename )
93- p .mkdir ()
93+ p .mkdir (mode = 0o700 )
9494 else :
95- p = make_numbered_dir (root = self .getbasetemp (), prefix = basename )
95+ p = make_numbered_dir (root = self .getbasetemp (), prefix = basename , mode = 0o700 )
9696 self ._trace ("mktemp" , p )
9797 return p
9898
9999 def getbasetemp (self ) -> Path :
100- """Return base temporary directory."""
100+ """Return the base temporary directory, creating it if needed ."""
101101 if self ._basetemp is not None :
102102 return self ._basetemp
103103
104104 if self ._given_basetemp is not None :
105105 basetemp = self ._given_basetemp
106- ensure_reset_dir (basetemp )
106+ if basetemp .exists ():
107+ rm_rf (basetemp )
108+ basetemp .mkdir (mode = 0o700 )
107109 basetemp = basetemp .resolve ()
108110 else :
109111 from_env = os .environ .get ("PYTEST_DEBUG_TEMPROOT" )
@@ -112,14 +114,37 @@ def getbasetemp(self) -> Path:
112114 # use a sub-directory in the temproot to speed-up
113115 # make_numbered_dir() call
114116 rootdir = temproot .joinpath (f"pytest-of-{ user } " )
115- rootdir .mkdir (exist_ok = True )
117+ rootdir .mkdir (mode = 0o700 , exist_ok = True )
118+ # Because we use exist_ok=True with a predictable name, make sure
119+ # we are the owners, to prevent any funny business (on unix, where
120+ # temproot is usually shared).
121+ # Also, to keep things private, fixup any world-readable temp
122+ # rootdir's permissions. Historically 0o755 was used, so we can't
123+ # just error out on this, at least for a while.
124+ if hasattr (os , "getuid" ):
125+ rootdir_stat = rootdir .stat ()
126+ uid = os .getuid ()
127+ # getuid shouldn't fail, but cpython defines such a case.
128+ # Let's hope for the best.
129+ if uid != - 1 :
130+ if rootdir_stat .st_uid != uid :
131+ raise OSError (
132+ f"The temporary directory { rootdir } is not owned by the current user. "
133+ "Fix this and try again."
134+ )
135+ if (rootdir_stat .st_mode & 0o077 ) != 0 :
136+ os .chmod (rootdir , rootdir_stat .st_mode & ~ 0o077 )
116137 basetemp = make_numbered_dir_with_cleanup (
117- prefix = "pytest-" , root = rootdir , keep = 3 , lock_timeout = LOCK_TIMEOUT
138+ prefix = "pytest-" ,
139+ root = rootdir ,
140+ keep = 3 ,
141+ lock_timeout = LOCK_TIMEOUT ,
142+ mode = 0o700 ,
118143 )
119144 assert basetemp is not None , basetemp
120- self ._basetemp = t = basetemp
121- self ._trace ("new basetemp" , t )
122- return t
145+ self ._basetemp = basetemp
146+ self ._trace ("new basetemp" , basetemp )
147+ return basetemp
123148
124149
125150@final
0 commit comments