add patch use-swap-in-memswap
[ext4-patch-queue.git] / clean-up-error-handling-in-ext4_fname_setup_filename
blob6f3ed393aae85daa790f77f8bd6d1adc175e9a0f
1 ext4 crypto: clean up error handling in ext4_fname_setup_filename
3 Fix a potential memory leak where fname->crypto_buf.name wouldn't get
4 freed in some error paths, and also make the error handling easier to
5 understand/audit.
7 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
9 ---
10  fs/ext4/crypto_fname.c | 35 ++++++++++++++++-------------------
11  1 file changed, 16 insertions(+), 19 deletions(-)
13 diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c
14 index 29a2dc9..23af41f 100644
15 --- a/fs/ext4/crypto_fname.c
16 +++ b/fs/ext4/crypto_fname.c
17 @@ -401,7 +401,7 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
18               ((iname->name[1] == '.') && (iname->len == 2))))) {
19                 fname->disk_name.name = (unsigned char *) iname->name;
20                 fname->disk_name.len = iname->len;
21 -               goto out;
22 +               return 0;
23         }
24         ret = ext4_get_encryption_info(dir);
25         if (ret)
26 @@ -411,19 +411,16 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
27                 ret = ext4_fname_crypto_alloc_buffer(dir, iname->len,
28                                                      &fname->crypto_buf);
29                 if (ret < 0)
30 -                       goto out;
31 +                       return ret;
32                 ret = ext4_fname_encrypt(dir, iname, &fname->crypto_buf);
33                 if (ret < 0)
34 -                       goto out;
35 +                       goto errout;
36                 fname->disk_name.name = fname->crypto_buf.name;
37                 fname->disk_name.len = fname->crypto_buf.len;
38 -               ret = 0;
39 -               goto out;
40 -       }
41 -       if (!lookup) {
42 -               ret = -EACCES;
43 -               goto out;
44 +               return 0;
45         }
46 +       if (!lookup)
47 +               return -EACCES;
49         /* We don't have the key and we are doing a lookup; decode the
50          * user-supplied name
51 @@ -431,19 +428,17 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
52         if (iname->name[0] == '_')
53                 bigname = 1;
54         if ((bigname && (iname->len != 33)) ||
55 -           (!bigname && (iname->len > 43))) {
56 -               ret = -ENOENT;
57 -       }
58 +           (!bigname && (iname->len > 43)))
59 +               return -ENOENT;
61         fname->crypto_buf.name = kmalloc(32, GFP_KERNEL);
62 -       if (fname->crypto_buf.name == NULL) {
63 -               ret = -ENOMEM;
64 -               goto out;
65 -       }
66 +       if (fname->crypto_buf.name == NULL)
67 +               return -ENOMEM;
68         ret = digest_decode(iname->name + bigname, iname->len - bigname,
69                             fname->crypto_buf.name);
70         if (ret < 0) {
71                 ret = -ENOENT;
72 -               goto out;
73 +               goto errout;
74         }
75         fname->crypto_buf.len = ret;
76         if (bigname) {
77 @@ -453,8 +448,10 @@ int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
78                 fname->disk_name.name = fname->crypto_buf.name;
79                 fname->disk_name.len = fname->crypto_buf.len;
80         }
81 -       ret = 0;
82 -out:
83 +       return 0;
84 +errout:
85 +       kfree(fname->crypto_buf.name);
86 +       fname->crypto_buf.name = NULL;
87         return ret;
88  }