diff options
Diffstat (limited to 'fs/jffs2/readinode.c')
| -rw-r--r-- | fs/jffs2/readinode.c | 19 | 
1 files changed, 13 insertions, 6 deletions
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index dc0437e8476..1ea349fff68 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -1266,19 +1266,25 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,  			/* Symlink's inode data is the target path. Read it and  			 * keep in RAM to facilitate quick follow symlink  			 * operation. */ -			f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL); +			uint32_t csize = je32_to_cpu(latest_node->csize); +			if (csize > JFFS2_MAX_NAME_LEN) { +				mutex_unlock(&f->sem); +				jffs2_do_clear_inode(c, f); +				return -ENAMETOOLONG; +			} +			f->target = kmalloc(csize + 1, GFP_KERNEL);  			if (!f->target) { -				JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize)); +				JFFS2_ERROR("can't allocate %u bytes of memory for the symlink target path cache\n", csize);  				mutex_unlock(&f->sem);  				jffs2_do_clear_inode(c, f);  				return -ENOMEM;  			}  			ret = jffs2_flash_read(c, ref_offset(rii.latest_ref) + sizeof(*latest_node), -						je32_to_cpu(latest_node->csize), &retlen, (char *)f->target); +					       csize, &retlen, (char *)f->target); -			if (ret  || retlen != je32_to_cpu(latest_node->csize)) { -				if (retlen != je32_to_cpu(latest_node->csize)) +			if (ret || retlen != csize) { +				if (retlen != csize)  					ret = -EIO;  				kfree(f->target);  				f->target = NULL; @@ -1287,7 +1293,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,  				return ret;  			} -			f->target[je32_to_cpu(latest_node->csize)] = '\0'; +			f->target[csize] = '\0';  			dbg_readinode("symlink's target '%s' cached\n", f->target);  		} @@ -1415,6 +1421,7 @@ int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i  		mutex_unlock(&f->sem);  		jffs2_do_clear_inode(c, f);  	} +	jffs2_xattr_do_crccheck_inode(c, ic);  	kfree (f);  	return ret;  }  |