github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/cmd/snap-confine/misc/0001-Add-printk-based-debugging-to-pivot_root.patch (about)

     1  From 1ef45eb31cacd58c4c62e1fd26aa63a1f3d031a7 Mon Sep 17 00:00:00 2001
     2  From: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
     3  Date: Thu, 29 Sep 2016 15:11:15 +0200
     4  Subject: [PATCH] Add printk-based debugging to pivot_root
     5  
     6  This patch changes pivot_root to make it obvious which error exit path
     7  was taken. It might be useful to apply to debug and investigate how
     8  undocumented requirements of pivot_root are not met.
     9  
    10  Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
    11  ---
    12   fs/namespace.c | 70 ++++++++++++++++++++++++++++++++++++++++++++--------------
    13   1 file changed, 53 insertions(+), 17 deletions(-)
    14  
    15  diff --git a/fs/namespace.c b/fs/namespace.c
    16  index 877fc2c..6e15d1d 100644
    17  --- a/fs/namespace.c
    18  +++ b/fs/namespace.c
    19  @@ -2993,57 +2993,93 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
    20   		return -EPERM;
    21   
    22   	error = user_path_dir(new_root, &new);
    23  -	if (error)
    24  +	if (error) {
    25  +		printk(KERN_ERR "user_path_dir(new_root, &new) returned an error\n");
    26   		goto out0;
    27  +	}
    28   
    29   	error = user_path_dir(put_old, &old);
    30  -	if (error)
    31  +	if (error) {
    32  +		printk(KERN_ERR "user_path_dir(put_old, &old) returned an error\n");
    33   		goto out1;
    34  +	}
    35   
    36   	error = security_sb_pivotroot(&old, &new);
    37  -	if (error)
    38  +	if (error) {
    39  +		printk(KERN_ERR "security_sb_pivotroot(&old, &new) returned an error\n");
    40   		goto out2;
    41  +	}
    42   
    43   	get_fs_root(current->fs, &root);
    44   	old_mp = lock_mount(&old);
    45   	error = PTR_ERR(old_mp);
    46  -	if (IS_ERR(old_mp))
    47  +	if (IS_ERR(old_mp)) {
    48  +		printk(KERN_ERR "IS_ERR(old_mp)\n");
    49   		goto out3;
    50  +	}
    51   
    52   	error = -EINVAL;
    53   	new_mnt = real_mount(new.mnt);
    54   	root_mnt = real_mount(root.mnt);
    55   	old_mnt = real_mount(old.mnt);
    56  -	if (IS_MNT_SHARED(old_mnt) ||
    57  -		IS_MNT_SHARED(new_mnt->mnt_parent) ||
    58  -		IS_MNT_SHARED(root_mnt->mnt_parent))
    59  +	if (IS_MNT_SHARED(old_mnt)) {
    60  +		printk(KERN_ERR "IS_MNT_SHARED(old_mnt)\n");
    61  +		goto out4;
    62  +	}
    63  +	if (IS_MNT_SHARED(new_mnt->mnt_parent)) {
    64  +		printk(KERN_ERR "IS_MNT_SHARED(new_mnt->mnt_parent)\n");
    65   		goto out4;
    66  -	if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
    67  +	}
    68  +	if (IS_MNT_SHARED(root_mnt->mnt_parent)) {
    69  +		printk(KERN_ERR "IS_MNT_SHARED(root_mnt->mnt_parent)\n");
    70   		goto out4;
    71  -	if (new_mnt->mnt.mnt_flags & MNT_LOCKED)
    72  +	}
    73  +	if (!check_mnt(root_mnt) || !check_mnt(new_mnt)) {
    74  +		printk(KERN_ERR "!check_mnt(root_mnt) || !check_mnt(new_mnt)\n");
    75  +		goto out4;
    76  +	}
    77  +	if (new_mnt->mnt.mnt_flags & MNT_LOCKED) {
    78  +		printk(KERN_ERR "new_mnt->mnt.mnt_flags & MNT_LOCKED\n");
    79   		goto out4;
    80  +	}
    81   	error = -ENOENT;
    82  -	if (d_unlinked(new.dentry))
    83  +	if (d_unlinked(new.dentry)) {
    84  +		printk(KERN_ERR "d_unlinked(new.dentry)\n");
    85   		goto out4;
    86  +	}
    87   	error = -EBUSY;
    88  -	if (new_mnt == root_mnt || old_mnt == root_mnt)
    89  +	if (new_mnt == root_mnt || old_mnt == root_mnt) {
    90  +		printk(KERN_ERR "new_mnt == root_mnt || old_mnt == root_mnt\n");
    91   		goto out4; /* loop, on the same file system  */
    92  +	}
    93   	error = -EINVAL;
    94  -	if (root.mnt->mnt_root != root.dentry)
    95  +	if (root.mnt->mnt_root != root.dentry) {
    96  +		printk(KERN_ERR "root.mnt->mnt_root != root.dentry\n");
    97   		goto out4; /* not a mountpoint */
    98  -	if (!mnt_has_parent(root_mnt))
    99  +	}
   100  +	if (!mnt_has_parent(root_mnt)) {
   101  +		printk(KERN_ERR "!mnt_has_parent(root_mnt)\n");
   102   		goto out4; /* not attached */
   103  +	}
   104   	root_mp = root_mnt->mnt_mp;
   105  -	if (new.mnt->mnt_root != new.dentry)
   106  +	if (new.mnt->mnt_root != new.dentry) {
   107  +		printk(KERN_ERR "new.mnt->mnt_root != new.dentry\n");
   108   		goto out4; /* not a mountpoint */
   109  -	if (!mnt_has_parent(new_mnt))
   110  +	}
   111  +	if (!mnt_has_parent(new_mnt)) {
   112  +		printk(KERN_ERR "!mnt_has_parent(new_mnt)\n");
   113   		goto out4; /* not attached */
   114  +	}
   115   	/* make sure we can reach put_old from new_root */
   116  -	if (!is_path_reachable(old_mnt, old.dentry, &new))
   117  +	if (!is_path_reachable(old_mnt, old.dentry, &new)) {
   118  +		printk(KERN_ERR "!is_path_reachable(old_mnt, old.dentry, &new)\n");
   119   		goto out4;
   120  +	}
   121   	/* make certain new is below the root */
   122  -	if (!is_path_reachable(new_mnt, new.dentry, &root))
   123  +	if (!is_path_reachable(new_mnt, new.dentry, &root)) {
   124  +		printk(KERN_ERR "!is_path_reachable(new_mnt, new.dentry, &root)\n");
   125   		goto out4;
   126  +	}
   127   	root_mp->m_count++; /* pin it so it won't go away */
   128   	lock_mount_hash();
   129   	detach_mnt(new_mnt, &parent_path);
   130  -- 
   131  2.7.4
   132