forked from mirrors/linux
		
	cgroup: fix the retry path of cgroup_mount()
If we hit the retry path, we'll call parse_cgroupfs_options() again,
but the string we pass to it has been modified by the previous call
to this function.
This bug can be observed by:
  # mount -t cgroup -o name=foo,cpuset xxx /mnt && umount /mnt && \
    mount -t cgroup -o name=foo,cpuset xxx /mnt
  mount: wrong fs type, bad option, bad superblock on xxx,
         missing codepage or helper program, or other error
  ...
The second mount passed "name=foo,cpuset" to the parser, and then it
hit the retry path and call the parser again, but this time the string
passed to the parser is "name=foo".
To fix this, we avoid calling parse_cgroupfs_options() again in this
case.
Signed-off-by: Li Zefan <lizefan@huawei.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									c9eaa447e7
								
							
						
					
					
						commit
						e37a06f109
					
				
					 1 changed files with 4 additions and 4 deletions
				
			
		| 
						 | 
					@ -1495,7 +1495,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!use_task_css_set_links)
 | 
						if (!use_task_css_set_links)
 | 
				
			||||||
		cgroup_enable_task_cg_lists();
 | 
							cgroup_enable_task_cg_lists();
 | 
				
			||||||
retry:
 | 
					
 | 
				
			||||||
	mutex_lock(&cgroup_tree_mutex);
 | 
						mutex_lock(&cgroup_tree_mutex);
 | 
				
			||||||
	mutex_lock(&cgroup_mutex);
 | 
						mutex_lock(&cgroup_mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1503,7 +1503,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 | 
				
			||||||
	ret = parse_cgroupfs_options(data, &opts);
 | 
						ret = parse_cgroupfs_options(data, &opts);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto out_unlock;
 | 
							goto out_unlock;
 | 
				
			||||||
 | 
					retry:
 | 
				
			||||||
	/* look for a matching existing root */
 | 
						/* look for a matching existing root */
 | 
				
			||||||
	if (!opts.subsys_mask && !opts.none && !opts.name) {
 | 
						if (!opts.subsys_mask && !opts.none && !opts.name) {
 | 
				
			||||||
		cgrp_dfl_root_visible = true;
 | 
							cgrp_dfl_root_visible = true;
 | 
				
			||||||
| 
						 | 
					@ -1562,9 +1562,9 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
 | 
				
			||||||
		if (!atomic_inc_not_zero(&root->cgrp.refcnt)) {
 | 
							if (!atomic_inc_not_zero(&root->cgrp.refcnt)) {
 | 
				
			||||||
			mutex_unlock(&cgroup_mutex);
 | 
								mutex_unlock(&cgroup_mutex);
 | 
				
			||||||
			mutex_unlock(&cgroup_tree_mutex);
 | 
								mutex_unlock(&cgroup_tree_mutex);
 | 
				
			||||||
			kfree(opts.release_agent);
 | 
					 | 
				
			||||||
			kfree(opts.name);
 | 
					 | 
				
			||||||
			msleep(10);
 | 
								msleep(10);
 | 
				
			||||||
 | 
								mutex_lock(&cgroup_tree_mutex);
 | 
				
			||||||
 | 
								mutex_lock(&cgroup_mutex);
 | 
				
			||||||
			goto retry;
 | 
								goto retry;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue