@@ -995,7 +995,8 @@ ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
ret = import_iovec(READ, vec, vlen, &iov, &iter);
if (ret >= 0) {
ret = do_iter_read(file, &iter, pos, flags);
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
}
return ret;
@@ -1014,7 +1015,8 @@ static ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
file_start_write(file);
ret = do_iter_write(file, &iter, pos, flags);
file_end_write(file);
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
}
return ret;
}
@@ -1184,7 +1186,8 @@ static size_t compat_readv(struct file *file,
ret = compat_import_iovec(READ, vec, vlen, &iov, &iter);
if (ret >= 0) {
ret = do_iter_read(file, &iter, pos, flags);
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
}
if (ret > 0)
add_rchar(current, ret);
@@ -1294,7 +1297,8 @@ static size_t compat_writev(struct file *file,
file_start_write(file);
ret = do_iter_write(file, &iter, pos, flags);
file_end_write(file);
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
}
if (ret > 0)
add_wchar(current, ret);
@@ -1368,7 +1368,8 @@ static long do_vmsplice(struct file *f, struct iov_iter *iter, unsigned int flag
error = import_iovec(type, uiov, nr_segs, &iov, &iter);
if (error >= 0) {
error = do_vmsplice(f.file, &iter, flags);
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
}
fdput(f);
return error;
@@ -1393,7 +1394,8 @@ static long do_vmsplice(struct file *f, struct iov_iter *iter, unsigned int flag
error = compat_import_iovec(type, iov32, nr_segs, &iov, &iter);
if (error >= 0) {
error = do_vmsplice(f.file, &iter, flags);
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
}
fdput(f);
return error;
@@ -2324,7 +2324,8 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
if (ctl_buf != ctl)
sock_kfree_s(sock->sk, ctl_buf, ctl_len);
out_freeiov:
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
return err;
}
@@ -38,7 +38,8 @@ static long compat_keyctl_instantiate_key_iov(
return ret;
ret = keyctl_instantiate_key_common(id, &from, ringid);
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
return ret;
}
@@ -1219,7 +1219,8 @@ long keyctl_instantiate_key_iov(key_serial_t id,
if (ret < 0)
return ret;
ret = keyctl_instantiate_key_common(id, &from, ringid);
- kfree(iov);
+ if (unlikely(iov))
+ kfree(iov);
return ret;
}
Although kfree(NULL) is valid it is slower that checking in the calling code. Most of the time passing NULL is unusual, but in the code that is reading iovecs from the user NULL is the normal case (only large SG vectors require kmalloc()). Add a check in the callers before calling kfree(). Signed-off-by: David Laight <david.laight@aculab.com> --- Note this patch probably needs splitting in 3. fs/read_write.c | 12 ++++++++---- fs/splice.c | 6 ++++-- net/socket.c | 3 ++- security/keys/compat.c | 3 ++- security/keys/keyctl.c | 3 ++- 5 files changed, 18 insertions(+), 9 deletions(-)