| From 6e40244a93002bddb51817ab38c297b8e2a8c7b1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 29 Apr 2021 22:54:15 -0700 |
| Subject: kfifo: fix ternary sign extension bugs |
| |
| From: Dan Carpenter <dan.carpenter@oracle.com> |
| |
| [ Upstream commit 926ee00ea24320052b46745ef4b00d91c05bd03d ] |
| |
| The intent with this code was to return negative error codes but instead |
| it returns positives. |
| |
| The problem is how type promotion works with ternary operations. These |
| functions return long, "ret" is an int and "copied" is a u32. The |
| negative error code is first cast to u32 so it becomes a high positive and |
| then cast to long where it's still a positive. |
| |
| We could fix this by declaring "ret" as a ssize_t but let's just get rid |
| of the ternaries instead. |
| |
| Link: https://lkml.kernel.org/r/YIE+/cK1tBzSuQPU@mwanda |
| Fixes: 5bf2b19320ec ("kfifo: add example files to the kernel sample directory") |
| Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> |
| Cc: Stefani Seibold <stefani@seibold.net> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| samples/kfifo/bytestream-example.c | 8 ++++++-- |
| samples/kfifo/inttype-example.c | 8 ++++++-- |
| samples/kfifo/record-example.c | 8 ++++++-- |
| 3 files changed, 18 insertions(+), 6 deletions(-) |
| |
| diff --git a/samples/kfifo/bytestream-example.c b/samples/kfifo/bytestream-example.c |
| index 2fca916d9edf..a7f5ee8b6edc 100644 |
| --- a/samples/kfifo/bytestream-example.c |
| +++ b/samples/kfifo/bytestream-example.c |
| @@ -124,8 +124,10 @@ static ssize_t fifo_write(struct file *file, const char __user *buf, |
| ret = kfifo_from_user(&test, buf, count, &copied); |
| |
| mutex_unlock(&write_lock); |
| + if (ret) |
| + return ret; |
| |
| - return ret ? ret : copied; |
| + return copied; |
| } |
| |
| static ssize_t fifo_read(struct file *file, char __user *buf, |
| @@ -140,8 +142,10 @@ static ssize_t fifo_read(struct file *file, char __user *buf, |
| ret = kfifo_to_user(&test, buf, count, &copied); |
| |
| mutex_unlock(&read_lock); |
| + if (ret) |
| + return ret; |
| |
| - return ret ? ret : copied; |
| + return copied; |
| } |
| |
| static const struct file_operations fifo_fops = { |
| diff --git a/samples/kfifo/inttype-example.c b/samples/kfifo/inttype-example.c |
| index 8dc3c2e7105a..a326a37e9163 100644 |
| --- a/samples/kfifo/inttype-example.c |
| +++ b/samples/kfifo/inttype-example.c |
| @@ -117,8 +117,10 @@ static ssize_t fifo_write(struct file *file, const char __user *buf, |
| ret = kfifo_from_user(&test, buf, count, &copied); |
| |
| mutex_unlock(&write_lock); |
| + if (ret) |
| + return ret; |
| |
| - return ret ? ret : copied; |
| + return copied; |
| } |
| |
| static ssize_t fifo_read(struct file *file, char __user *buf, |
| @@ -133,8 +135,10 @@ static ssize_t fifo_read(struct file *file, char __user *buf, |
| ret = kfifo_to_user(&test, buf, count, &copied); |
| |
| mutex_unlock(&read_lock); |
| + if (ret) |
| + return ret; |
| |
| - return ret ? ret : copied; |
| + return copied; |
| } |
| |
| static const struct file_operations fifo_fops = { |
| diff --git a/samples/kfifo/record-example.c b/samples/kfifo/record-example.c |
| index 2d7529eeb294..deb87a2e4e6b 100644 |
| --- a/samples/kfifo/record-example.c |
| +++ b/samples/kfifo/record-example.c |
| @@ -131,8 +131,10 @@ static ssize_t fifo_write(struct file *file, const char __user *buf, |
| ret = kfifo_from_user(&test, buf, count, &copied); |
| |
| mutex_unlock(&write_lock); |
| + if (ret) |
| + return ret; |
| |
| - return ret ? ret : copied; |
| + return copied; |
| } |
| |
| static ssize_t fifo_read(struct file *file, char __user *buf, |
| @@ -147,8 +149,10 @@ static ssize_t fifo_read(struct file *file, char __user *buf, |
| ret = kfifo_to_user(&test, buf, count, &copied); |
| |
| mutex_unlock(&read_lock); |
| + if (ret) |
| + return ret; |
| |
| - return ret ? ret : copied; |
| + return copied; |
| } |
| |
| static const struct file_operations fifo_fops = { |
| -- |
| 2.30.2 |
| |