From 4515746ea214d57c6aa7da0bab75d80f3011b823 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 13 Jan 2019 19:41:42 +0000 Subject: [PATCH 1/2] scst_dlm: Fix scst_read_file() The 'fs' register must be set before vfs_read() is called. kernel_read() does this but scst_read() not. Hence change the scst_read() call in the dlm code into a kernel_read() call. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7872 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_dlm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scst/src/scst_dlm.c b/scst/src/scst_dlm.c index ad65c46f9..7e60e014c 100644 --- a/scst/src/scst_dlm.c +++ b/scst/src/scst_dlm.c @@ -516,7 +516,7 @@ static int scst_read_file(const char *path, char *buf, int buf_len) goto out; } pos = 0; - ret = scst_read(f, buf, buf_len, &pos); + ret = kernel_read(f, buf, buf_len, &pos); if (ret >= 0) buf[min(ret, buf_len - 1)] = '\0'; filp_close(f, NULL); From b6d08e58079ac7e8f3083fde22cbb484a16bbc12 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 13 Jan 2019 19:43:31 +0000 Subject: [PATCH 2/2] scst: Complain loudly if 'fs' is incorrect Since not setting the fs register correctly leads to silent data corruption, if scst_read(), scst_write(), scst_readv() or scst_writev() is called, complain loudly if 'fs' has not been set correctly. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7873 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_lib.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 6d9d184af..0aeed0ae8 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -5946,6 +5946,14 @@ static void scst_complete_request_sense(struct scst_cmd *req_cmd) return; } +static int scst_cmp_fs_ds(void) +{ + mm_segment_t fs = get_fs(); + mm_segment_t ds = get_ds(); + + return memcmp(&fs, &ds, sizeof(fs)); +} + ssize_t scst_read(struct file *file, void *buf, size_t count, loff_t *pos) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) @@ -5954,6 +5962,8 @@ ssize_t scst_read(struct file *file, void *buf, size_t count, loff_t *pos) .iov_len = count }; + WARN_ON_ONCE(scst_cmp_fs_ds() != 0); + return scst_readv(file, &iov, 1, pos); #else return vfs_read(file, (void __force __user *)buf, count, pos); @@ -5970,6 +5980,8 @@ ssize_t scst_write(struct file *file, const void *buf, size_t count, .iov_len = count }; + WARN_ON_ONCE(scst_cmp_fs_ds() != 0); + return scst_writev(file, &iov, 1, pos); #else return vfs_write(file, (void __force __user *)buf, count, pos); @@ -5986,6 +5998,8 @@ ssize_t scst_readv(struct file *file, const struct iovec *vec, struct iov_iter iter; ssize_t ret; + WARN_ON_ONCE(scst_cmp_fs_ds() != 0); + ret = import_iovec(READ, (const struct iovec __force __user *)vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); if (ret < 0) @@ -6023,6 +6037,8 @@ ssize_t scst_writev(struct file *file, const struct iovec *vec, struct iov_iter iter; ssize_t ret; + WARN_ON_ONCE(scst_cmp_fs_ds() != 0); + ret = import_iovec(WRITE, (const struct iovec __force __user *)vec, vlen, ARRAY_SIZE(iovstack), &iov, &iter); if (ret < 0)