diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2014-07-07 09:28:51 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2014-07-07 09:28:51 -0400 |
commit | 233a01fa9c4c7c41238537e8db8434667ff28a2f (patch) | |
tree | eea525a1e50caf4f9fd3a67e62e36c15f28d645d /fs | |
parent | 7b3d8bf7718a8de8ac6a25ed7332c1c129839400 (diff) |
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
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fuse/inode.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 7b8fc7d33def..8474028d7848 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -478,6 +478,17 @@ static const match_table_t tokens = { | |||
478 | {OPT_ERR, NULL} | 478 | {OPT_ERR, NULL} |
479 | }; | 479 | }; |
480 | 480 | ||
481 | static int fuse_match_uint(substring_t *s, unsigned int *res) | ||
482 | { | ||
483 | int err = -ENOMEM; | ||
484 | char *buf = match_strdup(s); | ||
485 | if (buf) { | ||
486 | err = kstrtouint(buf, 10, res); | ||
487 | kfree(buf); | ||
488 | } | ||
489 | return err; | ||
490 | } | ||
491 | |||
481 | static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) | 492 | static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) |
482 | { | 493 | { |
483 | char *p; | 494 | char *p; |
@@ -488,6 +499,7 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) | |||
488 | while ((p = strsep(&opt, ",")) != NULL) { | 499 | while ((p = strsep(&opt, ",")) != NULL) { |
489 | int token; | 500 | int token; |
490 | int value; | 501 | int value; |
502 | unsigned uv; | ||
491 | substring_t args[MAX_OPT_ARGS]; | 503 | substring_t args[MAX_OPT_ARGS]; |
492 | if (!*p) | 504 | if (!*p) |
493 | continue; | 505 | continue; |
@@ -511,18 +523,18 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) | |||
511 | break; | 523 | break; |
512 | 524 | ||
513 | case OPT_USER_ID: | 525 | case OPT_USER_ID: |
514 | if (match_int(&args[0], &value)) | 526 | if (fuse_match_uint(&args[0], &uv)) |
515 | return 0; | 527 | return 0; |
516 | d->user_id = make_kuid(current_user_ns(), value); | 528 | d->user_id = make_kuid(current_user_ns(), uv); |
517 | if (!uid_valid(d->user_id)) | 529 | if (!uid_valid(d->user_id)) |
518 | return 0; | 530 | return 0; |
519 | d->user_id_present = 1; | 531 | d->user_id_present = 1; |
520 | break; | 532 | break; |
521 | 533 | ||
522 | case OPT_GROUP_ID: | 534 | case OPT_GROUP_ID: |
523 | if (match_int(&args[0], &value)) | 535 | if (fuse_match_uint(&args[0], &uv)) |
524 | return 0; | 536 | return 0; |
525 | d->group_id = make_kgid(current_user_ns(), value); | 537 | d->group_id = make_kgid(current_user_ns(), uv); |
526 | if (!gid_valid(d->group_id)) | 538 | if (!gid_valid(d->group_id)) |
527 | return 0; | 539 | return 0; |
528 | d->group_id_present = 1; | 540 | d->group_id_present = 1; |