forked from mirrors/linux
		
	fuse: handle large user and group ID
If the number in "user_id=N" or "group_id=N" mount options was larger than INT_MAX then fuse returned EINVAL. Fix this to handle all valid uid/gid values. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Cc: stable@vger.kernel.org
This commit is contained in:
		
							parent
							
								
									7b3d8bf771
								
							
						
					
					
						commit
						233a01fa9c
					
				
					 1 changed files with 16 additions and 4 deletions
				
			
		| 
						 | 
					@ -478,6 +478,17 @@ static const match_table_t tokens = {
 | 
				
			||||||
	{OPT_ERR,			NULL}
 | 
						{OPT_ERR,			NULL}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int fuse_match_uint(substring_t *s, unsigned int *res)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int err = -ENOMEM;
 | 
				
			||||||
 | 
						char *buf = match_strdup(s);
 | 
				
			||||||
 | 
						if (buf) {
 | 
				
			||||||
 | 
							err = kstrtouint(buf, 10, res);
 | 
				
			||||||
 | 
							kfree(buf);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return err;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
 | 
					static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char *p;
 | 
						char *p;
 | 
				
			||||||
| 
						 | 
					@ -488,6 +499,7 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
 | 
				
			||||||
	while ((p = strsep(&opt, ",")) != NULL) {
 | 
						while ((p = strsep(&opt, ",")) != NULL) {
 | 
				
			||||||
		int token;
 | 
							int token;
 | 
				
			||||||
		int value;
 | 
							int value;
 | 
				
			||||||
 | 
							unsigned uv;
 | 
				
			||||||
		substring_t args[MAX_OPT_ARGS];
 | 
							substring_t args[MAX_OPT_ARGS];
 | 
				
			||||||
		if (!*p)
 | 
							if (!*p)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
| 
						 | 
					@ -511,18 +523,18 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case OPT_USER_ID:
 | 
							case OPT_USER_ID:
 | 
				
			||||||
			if (match_int(&args[0], &value))
 | 
								if (fuse_match_uint(&args[0], &uv))
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			d->user_id = make_kuid(current_user_ns(), value);
 | 
								d->user_id = make_kuid(current_user_ns(), uv);
 | 
				
			||||||
			if (!uid_valid(d->user_id))
 | 
								if (!uid_valid(d->user_id))
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			d->user_id_present = 1;
 | 
								d->user_id_present = 1;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case OPT_GROUP_ID:
 | 
							case OPT_GROUP_ID:
 | 
				
			||||||
			if (match_int(&args[0], &value))
 | 
								if (fuse_match_uint(&args[0], &uv))
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			d->group_id = make_kgid(current_user_ns(), value);
 | 
								d->group_id = make_kgid(current_user_ns(), uv);
 | 
				
			||||||
			if (!gid_valid(d->group_id))
 | 
								if (!gid_valid(d->group_id))
 | 
				
			||||||
				return 0;
 | 
									return 0;
 | 
				
			||||||
			d->group_id_present = 1;
 | 
								d->group_id_present = 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue