summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/fat/fat.c2
-rw-r--r--fs/squashfs/sqfs.c2
-rw-r--r--fs/ubifs/ubifs.c71
3 files changed, 47 insertions, 28 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 31c136e3b9e..c1ccf30771a 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -71,7 +71,7 @@ static inline __u32 sect_to_block(__u32 sect, __u32 *off)
static int disk_rw(__u32 sect, __u32 nr_sect, void *buf, bool read)
{
- int ret;
+ int ret = 0;
__u8 *block = NULL;
__u32 rem, size, s, n;
const ulong blksz = cur_part_info.blksz;
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
index 543db8c7e9e..0768fc4a7b2 100644
--- a/fs/squashfs/sqfs.c
+++ b/fs/squashfs/sqfs.c
@@ -1636,6 +1636,8 @@ static int sqfs_read_nest(const char *filename, void *buf, loff_t offset,
*actread = finfo.size;
}
+ ret = 0;
+
out:
free(fragment);
free(datablock);
diff --git a/fs/ubifs/ubifs.c b/fs/ubifs/ubifs.c
index b0cc0d2e1b2..3f2e2037745 100644
--- a/fs/ubifs/ubifs.c
+++ b/fs/ubifs/ubifs.c
@@ -505,26 +505,32 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
{
int ret;
char *next;
- char fpath[128];
- char symlinkpath[128];
- char *name = fpath;
+ char *buf;
+ char *name;
unsigned long root_inum = 1;
unsigned long inum;
int symlink_count = 0; /* Don't allow symlink recursion */
- char link_name[64];
-
- strcpy(fpath, filename);
+ size_t filenamelen;
/* Remove all leading slashes */
- while (*name == '/')
- name++;
+ while (*filename == '/')
+ filename++;
+
+ filenamelen = strlen(filename);
+ buf = kmalloc(filenamelen + 1, GFP_NOFS);
+ if (!buf)
+ return -ENOMEM;
+ memcpy(buf, filename, filenamelen + 1);
+ name = buf;
/*
* Handle root-direcoty ('/')
*/
inum = root_inum;
- if (!name || *name == '\0')
+ if (!name || *name == '\0') {
+ kfree(buf);
return inum;
+ }
for (;;) {
struct inode *inode;
@@ -537,41 +543,53 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
while (*next == '/')
*(next++) = '\0';
}
-
ret = ubifs_finddir(sb, name, root_inum, &inum);
- if (!ret)
+ if (!ret) {
+ kfree(buf);
return 0;
+ }
inode = ubifs_iget(sb, inum);
- if (!inode)
+ if (!inode) {
+ kfree(buf);
return 0;
+ }
ui = ubifs_inode(inode);
if ((inode->i_mode & S_IFMT) == S_IFLNK) {
- char buf[128];
+ size_t newbufsize;
+ char *newbuf;
+ char *linkdata = ui->data;
+ size_t linklen = ui->data_len;
/* We have some sort of symlink recursion, bail out */
if (symlink_count++ > 8) {
ubifs_iput(inode);
printf("Symlink recursion, aborting\n");
+ kfree(buf);
return 0;
}
- memcpy(link_name, ui->data, ui->data_len);
- link_name[ui->data_len] = '\0';
- if (link_name[0] == '/') {
- /* Absolute path, redo everything without
- * the leading slash */
- next = name = link_name + 1;
+ while (linklen && *linkdata == '/') {
+ /* Absolute path, i.e. relative to root. */
root_inum = 1;
+ linkdata++;
+ linklen--;
+ }
+ newbufsize =
+ linklen + 1 + (next ? strlen(next) : 0) + 1;
+ newbuf = kmalloc(newbufsize, GFP_NOFS);
+ if (!newbuf) {
+ kfree(buf);
ubifs_iput(inode);
- continue;
+ return -ENOMEM;
}
- /* Relative to cur dir */
- sprintf(buf, "%s/%s",
- link_name, next == NULL ? "" : next);
- memcpy(symlinkpath, buf, sizeof(buf));
- next = name = symlinkpath;
+
+ memcpy(newbuf, linkdata, linklen);
+ sprintf(newbuf + linklen, "/%s", next ?: "");
+ kfree(buf);
+ buf = newbuf;
+ name = newbuf;
ubifs_iput(inode);
continue;
}
@@ -583,14 +601,13 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
/* Found the node! */
if (!next || *next == '\0') {
ubifs_iput(inode);
+ kfree(buf);
return inum;
}
root_inum = inum;
name = next;
}
-
- return 0;
}
int ubifs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info)