udf: Return -ENOMEM when allocation fails in udf_get_filename()
authorFabian Frederick <fabf@skynet.be>
Wed, 8 Apr 2015 19:23:51 +0000 (21:23 +0200)
committerJan Kara <jack@suse.cz>
Mon, 18 May 2015 09:23:03 +0000 (11:23 +0200)
Return -ENOMEM when allocation fails in udf_get_filename(). Update
udf_pc_to_char(), udf_readdir(), and udf_find_entry() to handle the
error appropriately. This allows us to pass appropriate error to
userspace instead of corrupting symlink contents by omitting some path
elements.

Signed-off-by: Fabian Frederick <fabf@skynet.be>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/udf/dir.c
fs/udf/namei.c
fs/udf/symlink.c
fs/udf/unicode.c

index 541a12b5792d3a296d864efc626d75d42f180ab4..fcf227eb2c51c952a3657a166d4315d8adf9a1e6 100644 (file)
@@ -168,7 +168,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
                }
 
                flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN);
-               if (!flen)
+               if (flen <= 0)
                        continue;
 
                tloc = lelb_to_cpu(cfi.icb.extLocation);
index 5c03f0dfb98bcd6f7b396431f5e9ed7f49d23c8d..51b1c31b55c83df67fe2063e5a763aa64142f56d 100644 (file)
@@ -234,7 +234,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
                        continue;
 
                flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN);
-               if (flen && udf_match(flen, fname, child->len, child->name))
+               if (flen > 0 && udf_match(flen, fname, child->len, child->name))
                        goto out_ok;
        }
 
index 8dfbc4025e2f39afcb204d5abe8b0dff5f5a8f7b..862535b3ba58a8a6f6ca3d23b35b0b66fee36c22 100644 (file)
@@ -82,6 +82,9 @@ static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
                        comp_len = udf_get_filename(sb, pc->componentIdent,
                                                    pc->lengthComponentIdent,
                                                    p, tolen);
+                       if (comp_len < 0)
+                               return comp_len;
+
                        p += comp_len;
                        tolen -= comp_len;
                        if (tolen == 0)
index b84fee372734bd494ba5eb86f5ce5c8c28b99b5a..4911c1d8488263176ce761cdabece1b509c734a3 100644 (file)
@@ -338,15 +338,17 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen,
                     uint8_t *dname, int dlen)
 {
        struct ustr *filename, *unifilename;
-       int len = 0;
+       int ret = 0;
 
        filename = kmalloc(sizeof(struct ustr), GFP_NOFS);
        if (!filename)
-               return 0;
+               return -ENOMEM;
 
        unifilename = kmalloc(sizeof(struct ustr), GFP_NOFS);
-       if (!unifilename)
+       if (!unifilename) {
+               ret = -ENOMEM;
                goto out1;
+       }
 
        if (udf_build_ustr_exact(unifilename, sname, slen))
                goto out2;
@@ -367,14 +369,14 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen,
        } else
                goto out2;
 
-       len = udf_translate_to_linux(dname, dlen,
+       ret = udf_translate_to_linux(dname, dlen,
                                     filename->u_name, filename->u_len,
                                     unifilename->u_name, unifilename->u_len);
 out2:
        kfree(unifilename);
 out1:
        kfree(filename);
-       return len;
+       return ret;
 }
 
 int udf_put_filename(struct super_block *sb, const uint8_t *sname,