1818***/
1919
2020#include <fcntl.h>
21+ #include <linux/magic.h>
2122#ifdef HAVE_ACL
2223#include <sys/acl.h>
2324#endif
2425#include <sys/stat.h>
26+ #include <sys/vfs.h>
2527#include <unistd.h>
2628
2729#include "acl-util.h"
2830#include "dirent-util.h"
2931#include "fd-util.h"
32+ #include "missing.h"
3033#include "nspawn-patch-uid.h"
34+ #include "stat-util.h"
3135#include "stdio-util.h"
3236#include "string-util.h"
3337#include "strv.h"
@@ -276,12 +280,46 @@ static int patch_fd(int fd, const char *name, const struct stat *st, uid_t shift
276280 return r > 0 || changed ;
277281}
278282
283+ static int is_procfs_sysfs_or_suchlike (int fd ) {
284+ struct statfs sfs ;
285+
286+ assert (fd >= 0 );
287+
288+ if (fstatfs (fd , & sfs ) < 0 )
289+ return - errno ;
290+
291+ return F_TYPE_EQUAL (sfs .f_type , BINFMTFS_MAGIC ) ||
292+ F_TYPE_EQUAL (sfs .f_type , CGROUP_SUPER_MAGIC ) ||
293+ F_TYPE_EQUAL (sfs .f_type , CGROUP2_SUPER_MAGIC ) ||
294+ F_TYPE_EQUAL (sfs .f_type , DEBUGFS_MAGIC ) ||
295+ F_TYPE_EQUAL (sfs .f_type , DEVPTS_SUPER_MAGIC ) ||
296+ F_TYPE_EQUAL (sfs .f_type , EFIVARFS_MAGIC ) ||
297+ F_TYPE_EQUAL (sfs .f_type , HUGETLBFS_MAGIC ) ||
298+ F_TYPE_EQUAL (sfs .f_type , MQUEUE_MAGIC ) ||
299+ F_TYPE_EQUAL (sfs .f_type , PROC_SUPER_MAGIC ) ||
300+ F_TYPE_EQUAL (sfs .f_type , PSTOREFS_MAGIC ) ||
301+ F_TYPE_EQUAL (sfs .f_type , SELINUX_MAGIC ) ||
302+ F_TYPE_EQUAL (sfs .f_type , SMACK_MAGIC ) ||
303+ F_TYPE_EQUAL (sfs .f_type , SYSFS_MAGIC );
304+ }
305+
279306static int recurse_fd (int fd , bool donate_fd , const struct stat * st , uid_t shift ) {
280307 bool changed = false;
281308 int r ;
282309
283310 assert (fd >= 0 );
284311
312+ /* We generally want to permit crossing of mount boundaries when patching the UIDs/GIDs. However, we
313+ * probably shouldn't do this for /proc and /sys if that is already mounted into place. Hence, let's
314+ * stop the recursion when we hit a procfs or sysfs file system. */
315+ r = is_procfs_sysfs_or_suchlike (fd );
316+ if (r < 0 )
317+ goto finish ;
318+ if (r > 0 ) {
319+ r = 0 ; /* don't recurse */
320+ goto finish ;
321+ }
322+
285323 r = patch_fd (fd , NULL , st , shift );
286324 if (r < 0 )
287325 goto finish ;
@@ -294,8 +332,10 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift
294332 int copy ;
295333
296334 copy = fcntl (fd , F_DUPFD_CLOEXEC , 3 );
297- if (copy < 0 )
298- return - errno ;
335+ if (copy < 0 ) {
336+ r = - errno ;
337+ goto finish ;
338+ }
299339
300340 fd = copy ;
301341 donate_fd = true;
0 commit comments