diff options
author | Linus Torvalds | 2021-02-22 13:25:37 -0800 |
---|---|---|
committer | Linus Torvalds | 2021-02-22 13:25:37 -0800 |
commit | 9fe190462668d4dc6db56e819322624cbfda919b (patch) | |
tree | 2a9415b7b149cf7d65b36869a8489c0a6d66320f | |
parent | db990385427c278eef56aac2e2588ec8b8cab5b4 (diff) | |
parent | b9bffa10b267b045e2c106db75b311216d669529 (diff) |
Merge tag 'fs_for_v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull isofs, udf, and quota updates from Jan Kara:
"Several udf, isofs, and quota fixes"
* tag 'fs_for_v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
parser: Fix kernel-doc markups
udf: handle large user and group ID
isofs: handle large user and group ID
parser: add unsigned int parser
udf: fix silent AED tagLocation corruption
isofs: release buffer head before return
quota: Fix memory leak when handling corrupted quota file
-rw-r--r-- | fs/isofs/dir.c | 1 | ||||
-rw-r--r-- | fs/isofs/inode.c | 9 | ||||
-rw-r--r-- | fs/isofs/namei.c | 1 | ||||
-rw-r--r-- | fs/quota/quota_v2.c | 11 | ||||
-rw-r--r-- | fs/udf/inode.c | 9 | ||||
-rw-r--r-- | fs/udf/super.c | 9 | ||||
-rw-r--r-- | include/linux/parser.h | 1 | ||||
-rw-r--r-- | lib/parser.c | 44 |
8 files changed, 60 insertions, 25 deletions
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c index f0fe641893a5..b9e6a7ec78be 100644 --- a/fs/isofs/dir.c +++ b/fs/isofs/dir.c @@ -152,6 +152,7 @@ static int do_isofs_readdir(struct inode *inode, struct file *file, printk(KERN_NOTICE "iso9660: Corrupted directory entry" " in block %lu of inode %lu\n", block, inode->i_ino); + brelse(bh); return -EIO; } diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index ec90773527ee..21edc423b79f 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -339,6 +339,7 @@ static int parse_options(char *options, struct iso9660_options *popt) { char *p; int option; + unsigned int uv; popt->map = 'n'; popt->rock = 1; @@ -434,17 +435,17 @@ static int parse_options(char *options, struct iso9660_options *popt) case Opt_ignore: break; case Opt_uid: - if (match_int(&args[0], &option)) + if (match_uint(&args[0], &uv)) return 0; - popt->uid = make_kuid(current_user_ns(), option); + popt->uid = make_kuid(current_user_ns(), uv); if (!uid_valid(popt->uid)) return 0; popt->uid_set = 1; break; case Opt_gid: - if (match_int(&args[0], &option)) + if (match_uint(&args[0], &uv)) return 0; - popt->gid = make_kgid(current_user_ns(), option); + popt->gid = make_kgid(current_user_ns(), uv); if (!gid_valid(popt->gid)) return 0; popt->gid_set = 1; diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c index 402769881c32..58f80e1b3ac0 100644 --- a/fs/isofs/namei.c +++ b/fs/isofs/namei.c @@ -102,6 +102,7 @@ isofs_find_entry(struct inode *dir, struct dentry *dentry, printk(KERN_NOTICE "iso9660: Corrupted directory entry" " in block %lu of inode %lu\n", block, dir->i_ino); + brelse(bh); return 0; } diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index c21106557a37..b1467f3921c2 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -164,19 +164,24 @@ static int v2_read_file_info(struct super_block *sb, int type) quota_error(sb, "Number of blocks too big for quota file size (%llu > %llu).", (loff_t)qinfo->dqi_blocks << qinfo->dqi_blocksize_bits, i_size_read(sb_dqopt(sb)->files[type])); - goto out; + goto out_free; } if (qinfo->dqi_free_blk >= qinfo->dqi_blocks) { quota_error(sb, "Free block number too big (%u >= %u).", qinfo->dqi_free_blk, qinfo->dqi_blocks); - goto out; + goto out_free; } if (qinfo->dqi_free_entry >= qinfo->dqi_blocks) { quota_error(sb, "Block with free entry too big (%u >= %u).", qinfo->dqi_free_entry, qinfo->dqi_blocks); - goto out; + goto out_free; } ret = 0; +out_free: + if (ret) { + kfree(info->dqi_priv); + info->dqi_priv = NULL; + } out: up_read(&dqopt->dqio_sem); return ret; diff --git a/fs/udf/inode.c b/fs/udf/inode.c index bb89c3e43212..0dd2f93ac048 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c @@ -544,11 +544,14 @@ static int udf_do_extend_file(struct inode *inode, udf_write_aext(inode, last_pos, &last_ext->extLocation, last_ext->extLength, 1); + /* - * We've rewritten the last extent but there may be empty - * indirect extent after it - enter it. + * We've rewritten the last extent. If we are going to add + * more extents, we may need to enter possible following + * empty indirect extent. */ - udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); + if (new_block_bytes || prealloc_len) + udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0); } /* Managed to do everything necessary? */ diff --git a/fs/udf/super.c b/fs/udf/super.c index d0df217f4712..2f83c1204e20 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -459,6 +459,7 @@ static int udf_parse_options(char *options, struct udf_options *uopt, { char *p; int option; + unsigned int uv; uopt->novrs = 0; uopt->session = 0xFFFFFFFF; @@ -508,17 +509,17 @@ static int udf_parse_options(char *options, struct udf_options *uopt, uopt->flags &= ~(1 << UDF_FLAG_USE_SHORT_AD); break; case Opt_gid: - if (match_int(args, &option)) + if (match_uint(args, &uv)) return 0; - uopt->gid = make_kgid(current_user_ns(), option); + uopt->gid = make_kgid(current_user_ns(), uv); if (!gid_valid(uopt->gid)) return 0; uopt->flags |= (1 << UDF_FLAG_GID_SET); break; case Opt_uid: - if (match_int(args, &option)) + if (match_uint(args, &uv)) return 0; - uopt->uid = make_kuid(current_user_ns(), option); + uopt->uid = make_kuid(current_user_ns(), uv); if (!uid_valid(uopt->uid)) return 0; uopt->flags |= (1 << UDF_FLAG_UID_SET); diff --git a/include/linux/parser.h b/include/linux/parser.h index 89e2b23fb888..dd79f45a37b8 100644 --- a/include/linux/parser.h +++ b/include/linux/parser.h @@ -29,6 +29,7 @@ typedef struct { int match_token(char *, const match_table_t table, substring_t args[]); int match_int(substring_t *, int *result); +int match_uint(substring_t *s, unsigned int *result); int match_u64(substring_t *, u64 *result); int match_octal(substring_t *, int *result); int match_hex(substring_t *, int *result); diff --git a/lib/parser.c b/lib/parser.c index f5b3e5d7a7f9..7a5769db389f 100644 --- a/lib/parser.c +++ b/lib/parser.c @@ -11,7 +11,7 @@ #include <linux/string.h> /** - * match_one: - Determines if a string matches a simple pattern + * match_one - Determines if a string matches a simple pattern * @s: the string to examine for presence of the pattern * @p: the string containing the pattern * @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match @@ -89,7 +89,7 @@ static int match_one(char *s, const char *p, substring_t args[]) } /** - * match_token: - Find a token (and optional args) in a string + * match_token - Find a token (and optional args) in a string * @s: the string to examine for token/argument pairs * @table: match_table_t describing the set of allowed option tokens and the * arguments that may be associated with them. Must be terminated with a @@ -114,7 +114,7 @@ int match_token(char *s, const match_table_t table, substring_t args[]) EXPORT_SYMBOL(match_token); /** - * match_number: scan a number in the given base from a substring_t + * match_number - scan a number in the given base from a substring_t * @s: substring to be scanned * @result: resulting integer on success * @base: base to use when converting string @@ -147,7 +147,7 @@ static int match_number(substring_t *s, int *result, int base) } /** - * match_u64int: scan a number in the given base from a substring_t + * match_u64int - scan a number in the given base from a substring_t * @s: substring to be scanned * @result: resulting u64 on success * @base: base to use when converting string @@ -174,7 +174,7 @@ static int match_u64int(substring_t *s, u64 *result, int base) } /** - * match_int: - scan a decimal representation of an integer from a substring_t + * match_int - scan a decimal representation of an integer from a substring_t * @s: substring_t to be scanned * @result: resulting integer on success * @@ -188,8 +188,30 @@ int match_int(substring_t *s, int *result) } EXPORT_SYMBOL(match_int); +/* + * match_uint - scan a decimal representation of an integer from a substring_t + * @s: substring_t to be scanned + * @result: resulting integer on success + * + * Description: Attempts to parse the &substring_t @s as a decimal integer. On + * success, sets @result to the integer represented by the string and returns 0. + * Returns -ENOMEM, -EINVAL, or -ERANGE on failure. + */ +int match_uint(substring_t *s, unsigned int *result) +{ + int err = -ENOMEM; + char *buf = match_strdup(s); + + if (buf) { + err = kstrtouint(buf, 10, result); + kfree(buf); + } + return err; +} +EXPORT_SYMBOL(match_uint); + /** - * match_u64: - scan a decimal representation of a u64 from + * match_u64 - scan a decimal representation of a u64 from * a substring_t * @s: substring_t to be scanned * @result: resulting unsigned long long on success @@ -206,7 +228,7 @@ int match_u64(substring_t *s, u64 *result) EXPORT_SYMBOL(match_u64); /** - * match_octal: - scan an octal representation of an integer from a substring_t + * match_octal - scan an octal representation of an integer from a substring_t * @s: substring_t to be scanned * @result: resulting integer on success * @@ -221,7 +243,7 @@ int match_octal(substring_t *s, int *result) EXPORT_SYMBOL(match_octal); /** - * match_hex: - scan a hex representation of an integer from a substring_t + * match_hex - scan a hex representation of an integer from a substring_t * @s: substring_t to be scanned * @result: resulting integer on success * @@ -236,7 +258,7 @@ int match_hex(substring_t *s, int *result) EXPORT_SYMBOL(match_hex); /** - * match_wildcard: - parse if a string matches given wildcard pattern + * match_wildcard - parse if a string matches given wildcard pattern * @pattern: wildcard pattern * @str: the string to be parsed * @@ -287,7 +309,7 @@ bool match_wildcard(const char *pattern, const char *str) EXPORT_SYMBOL(match_wildcard); /** - * match_strlcpy: - Copy the characters from a substring_t to a sized buffer + * match_strlcpy - Copy the characters from a substring_t to a sized buffer * @dest: where to copy to * @src: &substring_t to copy * @size: size of destination buffer @@ -310,7 +332,7 @@ size_t match_strlcpy(char *dest, const substring_t *src, size_t size) EXPORT_SYMBOL(match_strlcpy); /** - * match_strdup: - allocate a new string with the contents of a substring_t + * match_strdup - allocate a new string with the contents of a substring_t * @s: &substring_t to copy * * Description: Allocates and returns a string filled with the contents of |