@@ -1251,6 +1251,8 @@ class Sandbox:
1251
1251
"/proc/cgroups" ,
1252
1252
"/proc/mounts" ,
1253
1253
"/proc/version" ,
1254
+ "/proc/sys/kernel/unprivileged_userns_clone" ,
1255
+ "/proc/sys/kernel/unprivileged_userns_apparmor_policy" ,
1254
1256
)
1255
1257
1256
1258
# Other commands worth running when dumping debug logs.
@@ -1372,8 +1374,9 @@ def __init__(self, libc, log_path, max_sandbox_ram_bytes, do_resource_limiting):
1372
1374
self ._log_path = log_path
1373
1375
self ._max_sandbox_ram_bytes = max_sandbox_ram_bytes
1374
1376
self ._do_resource_limiting = do_resource_limiting
1375
- self ._my_euid = None
1376
- self ._my_egid = None
1377
+ self ._my_uids = None
1378
+ self ._my_gids = None
1379
+ self ._initial_status_data = None
1377
1380
self ._checkpoint = None
1378
1381
self ._cgroup_controllers = None
1379
1382
self ._needed_controllers = set ()
@@ -1386,6 +1389,7 @@ def __init__(self, libc, log_path, max_sandbox_ram_bytes, do_resource_limiting):
1386
1389
# Save EUID and EGID before we move to a new user namespace.
1387
1390
("save_euid" , self ._save_euid ),
1388
1391
("save_egid" , self ._save_egid ),
1392
+ ("save_proc_self_status" , self ._save_proc_self_status ),
1389
1393
("unshare_user" , self ._unshare_user ),
1390
1394
# Map our current user as being root in the new user namespace.
1391
1395
("write_uid_map" , self ._write_uid_map ),
@@ -1530,19 +1534,8 @@ def __init__(self, libc, log_path, max_sandbox_ram_bytes, do_resource_limiting):
1530
1534
)
1531
1535
)
1532
1536
1533
- def _status (self ):
1534
- """
1535
- Return the current switcheroo status.
1536
-
1537
- :return: The last successful operation name, "UNSTARTED" if unstarted, or "OK" if all done, and some information.
1538
- """
1539
- main_status = self ._checkpoint
1540
- if self ._checkpoint is None :
1541
- main_status = "UNSTARTED"
1542
- if self ._checkpoint == self ._operations [- 1 ][0 ]:
1543
- main_status = "OK"
1544
- my_pid = os .getpid ()
1545
- status_line = f"{ main_status } (euid={ self ._my_euid } egid={ self ._my_egid } pid={ my_pid } do_resource_limiting={ self ._do_resource_limiting } initial_cgroup_name={ self ._initial_cgroup_name } codeeval_cgroup_name={ self ._codeeval_cgroup_name } controllers={ self ._cgroup_controllers } )"
1537
+ def _read_proc_self_status (self ):
1538
+ """Read /proc/self/status and return some of it as a dictionary."""
1546
1539
want_headers = (
1547
1540
"Name" ,
1548
1541
"Umask" ,
@@ -1562,20 +1555,35 @@ def _status(self):
1562
1555
"Seccomp" ,
1563
1556
"Seccomp_filters" ,
1564
1557
)
1565
- got_headers = {}
1558
+ status_data = {}
1559
+ with self ._open ("/proc/self/status" , "rb" ) as status_f :
1560
+ for line in status_f .read ().decode ("utf-8" ).splitlines ():
1561
+ for header in want_headers :
1562
+ if line .startswith (f"{ header } :" ):
1563
+ status_data [header ] = line .split (":" )[1 ].strip ()
1564
+ break
1565
+ return status_data
1566
+
1567
+ def _status (self ):
1568
+ """
1569
+ Return the current switcheroo status.
1570
+
1571
+ :return: The last successful operation name, "UNSTARTED" if unstarted, or "OK" if all done, and some information.
1572
+ """
1573
+ main_status = self ._checkpoint
1574
+ if self ._checkpoint is None :
1575
+ main_status = "UNSTARTED"
1576
+ if self ._checkpoint == self ._operations [- 1 ][0 ]:
1577
+ main_status = "OK"
1578
+ my_pid = os .getpid ()
1579
+ status_line = f"{ main_status } (uids={ self ._my_uids } gids={ self ._my_gids } pid={ my_pid } initial_proc_self_status={ self ._initial_status_data } do_resource_limiting={ self ._do_resource_limiting } initial_cgroup_name={ self ._initial_cgroup_name } codeeval_cgroup_name={ self ._codeeval_cgroup_name } controllers={ self ._cgroup_controllers } )"
1566
1580
try :
1567
- with self ._open ("/proc/self/status" , "rb" ) as status_f :
1568
- for line in status_f .read ().decode ("utf-8" ).splitlines ():
1569
- for header in want_headers :
1570
- if line .startswith (f"{ header } :" ):
1571
- got_headers [header ] = line .split (":" )[1 ].strip ()
1572
- break
1581
+ status_data = self ._read_proc_self_status ()
1573
1582
except OSError as e :
1574
- status_line += f" (error opening /proc/self/status: { e } )"
1583
+ status_line += f" (error parsing /proc/self/status: { e } )"
1575
1584
else :
1576
- for header in want_headers :
1577
- got_value = got_headers .get (header )
1578
- status_line += f" { header } ={ got_value } "
1585
+ for header , value in status_data .items ():
1586
+ status_line += f" { header } ={ value } "
1579
1587
if self ._do_resource_limiting :
1580
1588
cgroupfs_data = []
1581
1589
for cgroup_components in (
@@ -1738,10 +1746,13 @@ def _open(self, path, mode):
1738
1746
raise OSError (f"opening { path } mode={ mode } : { e } " )
1739
1747
1740
1748
def _save_euid (self ):
1741
- self ._my_euid = os .geteuid ()
1749
+ self ._my_uids = os .getresuid ()
1742
1750
1743
1751
def _save_egid (self ):
1744
- self ._my_egid = os .getegid ()
1752
+ self ._my_gids = os .getresgid ()
1753
+
1754
+ def _save_proc_self_status (self ):
1755
+ self ._initial_status_data = self ._read_proc_self_status ()
1745
1756
1746
1757
def _unshare_user (self ):
1747
1758
Sandbox .unshare (
@@ -1750,15 +1761,15 @@ def _unshare_user(self):
1750
1761
1751
1762
def _write_uid_map (self ):
1752
1763
with self ._open ("/proc/self/uid_map" , "wb" ) as uid_map_f :
1753
- uid_map_f .write (f"0 { self ._my_euid } 1\n " .encode ("ascii" ))
1764
+ uid_map_f .write (f"0 { self ._my_uids [ 1 ] } 1\n " .encode ("ascii" ))
1754
1765
1755
1766
def _write_setgroups (self ):
1756
1767
with self ._open ("/proc/self/setgroups" , "wb" ) as setgroups_f :
1757
1768
setgroups_f .write (b"deny" )
1758
1769
1759
1770
def _write_gid_map (self ):
1760
1771
with self ._open ("/proc/self/gid_map" , "wb" ) as gid_map_f :
1761
- gid_map_f .write (f"0 { self ._my_egid } 1\n " .encode ("ascii" ))
1772
+ gid_map_f .write (f"0 { self ._my_gids [ 1 ] } 1\n " .encode ("ascii" ))
1762
1773
1763
1774
def _find_self_in_cgroup_hierarchy (self ):
1764
1775
my_pid = os .getpid ()
@@ -3415,9 +3426,14 @@ def _run(self) -> subprocess.CompletedProcess:
3415
3426
logs = {}
3416
3427
3417
3428
def process_log (filename , log_line ):
3418
- if self ._debug or (
3419
- log_line and log_line [0 ] in "WEF"
3420
- ): # Warning, Error, Fatal
3429
+ if (
3430
+ self ._debug
3431
+ or not filename .endswith (".txt" ) # Not a gVisor log file
3432
+ or ( # gVisor log file
3433
+ log_line
3434
+ and log_line [0 ] in "WEF" # WEF: Warning, Error, Fatal
3435
+ )
3436
+ ):
3421
3437
if filename not in logs :
3422
3438
logs [filename ] = []
3423
3439
logs [filename ].append (log_line )
0 commit comments