diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/fat/fat.c | 2 | ||||
| -rw-r--r-- | fs/squashfs/sqfs.c | 2 | ||||
| -rw-r--r-- | fs/ubifs/ubifs.c | 71 |
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) |
