| From 58def9e343e4bbe9f563f5baf713c107b6e2a986 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 9ca3e4400c98..ecae2139274f 100644 |
| --- a/samples/kfifo/bytestream-example.c |
| +++ b/samples/kfifo/bytestream-example.c |
| @@ -122,8 +122,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, |
| @@ -138,8 +140,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 6cdeb72f83f1..7b4489e7a9a5 100644 |
| --- a/samples/kfifo/inttype-example.c |
| +++ b/samples/kfifo/inttype-example.c |
| @@ -115,8 +115,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, |
| @@ -131,8 +133,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 79ae8bb04120..eafe0838997d 100644 |
| --- a/samples/kfifo/record-example.c |
| +++ b/samples/kfifo/record-example.c |
| @@ -129,8 +129,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, |
| @@ -145,8 +147,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 |
| |