[PATCH] kfifo: fix ternary sign extension bugs

From: Dan Carpenter
Date: Thu Apr 22 2021 - 05:17:09 EST


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.

Fixes: 5bf2b19320ec ("kfifo: add example files to the kernel sample directory")
Signed-off-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>
---
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 c406f03ee551..5a90aa527877 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 proc_ops fifo_proc_ops = {
diff --git a/samples/kfifo/inttype-example.c b/samples/kfifo/inttype-example.c
index 78977fc4a23f..e5403d8c971a 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 proc_ops fifo_proc_ops = {
diff --git a/samples/kfifo/record-example.c b/samples/kfifo/record-example.c
index c507998a2617..f64f3d62d6c2 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 proc_ops fifo_proc_ops = {
--
2.30.2