Patch "libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value" has been added to the 4.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     libfs-add-define_simple_attribute_signed-for-signed-.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit e8e550cd8a52c91375e06392e134722dc0e3fb1e
Author: Akinobu Mita <akinobu.mita@xxxxxxxxx>
Date:   Tue Sep 20 02:24:16 2022 +0900

    libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value
    
    [ Upstream commit 2e41f274f9aa71cdcc69dc1f26a3f9304a651804 ]
    
    Patch series "fix error when writing negative value to simple attribute
    files".
    
    The simple attribute files do not accept a negative value since the commit
    488dac0c9237 ("libfs: fix error cast of negative value in
    simple_attr_write()"), but some attribute files want to accept a negative
    value.
    
    This patch (of 3):
    
    The simple attribute files do not accept a negative value since the commit
    488dac0c9237 ("libfs: fix error cast of negative value in
    simple_attr_write()"), so we have to use a 64-bit value to write a
    negative value.
    
    This adds DEFINE_SIMPLE_ATTRIBUTE_SIGNED for a signed value.
    
    Link: https://lkml.kernel.org/r/20220919172418.45257-1-akinobu.mita@xxxxxxxxx
    Link: https://lkml.kernel.org/r/20220919172418.45257-2-akinobu.mita@xxxxxxxxx
    Fixes: 488dac0c9237 ("libfs: fix error cast of negative value in simple_attr_write()")
    Signed-off-by: Akinobu Mita <akinobu.mita@xxxxxxxxx>
    Reported-by: Zhao Gongyi <zhaogongyi@xxxxxxxxxx>
    Reviewed-by: David Hildenbrand <david@xxxxxxxxxx>
    Reviewed-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Cc: Alexander Viro <viro@xxxxxxxxxxxxxxxxxx>
    Cc: Jonathan Corbet <corbet@xxxxxxx>
    Cc: Oscar Salvador <osalvador@xxxxxxx>
    Cc: Rafael J. Wysocki <rafael@xxxxxxxxxx>
    Cc: Shuah Khan <shuah@xxxxxxxxxx>
    Cc: Wei Yongjun <weiyongjun1@xxxxxxxxxx>
    Cc: Yicong Yang <yangyicong@xxxxxxxxxxxxx>
    Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/libfs.c b/fs/libfs.c
index 835d25e33509..75eeddc35b57 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -861,8 +861,8 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
 EXPORT_SYMBOL_GPL(simple_attr_read);
 
 /* interpret the buffer as a number to call the set function with */
-ssize_t simple_attr_write(struct file *file, const char __user *buf,
-			  size_t len, loff_t *ppos)
+static ssize_t simple_attr_write_xsigned(struct file *file, const char __user *buf,
+			  size_t len, loff_t *ppos, bool is_signed)
 {
 	struct simple_attr *attr;
 	unsigned long long val;
@@ -883,7 +883,10 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
 		goto out;
 
 	attr->set_buf[size] = '\0';
-	ret = kstrtoull(attr->set_buf, 0, &val);
+	if (is_signed)
+		ret = kstrtoll(attr->set_buf, 0, &val);
+	else
+		ret = kstrtoull(attr->set_buf, 0, &val);
 	if (ret)
 		goto out;
 	ret = attr->set(attr->data, val);
@@ -893,8 +896,21 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf,
 	mutex_unlock(&attr->mutex);
 	return ret;
 }
+
+ssize_t simple_attr_write(struct file *file, const char __user *buf,
+			  size_t len, loff_t *ppos)
+{
+	return simple_attr_write_xsigned(file, buf, len, ppos, false);
+}
 EXPORT_SYMBOL_GPL(simple_attr_write);
 
+ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
+			  size_t len, loff_t *ppos)
+{
+	return simple_attr_write_xsigned(file, buf, len, ppos, true);
+}
+EXPORT_SYMBOL_GPL(simple_attr_write_signed);
+
 /**
  * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
  * @sb:		filesystem to do the file handle conversion on
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9e4a75005280..a794954e2c8e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3132,7 +3132,7 @@ void simple_transaction_set(struct file *file, size_t n);
  * All attributes contain a text representation of a numeric value
  * that are accessed with the get() and set() functions.
  */
-#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)		\
+#define DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, __is_signed)	\
 static int __fops ## _open(struct inode *inode, struct file *file)	\
 {									\
 	__simple_attr_check_format(__fmt, 0ull);			\
@@ -3143,10 +3143,16 @@ static const struct file_operations __fops = {				\
 	.open	 = __fops ## _open,					\
 	.release = simple_attr_release,					\
 	.read	 = simple_attr_read,					\
-	.write	 = simple_attr_write,					\
+	.write	 = (__is_signed) ? simple_attr_write_signed : simple_attr_write,	\
 	.llseek	 = generic_file_llseek,					\
 }
 
+#define DEFINE_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt)		\
+	DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, false)
+
+#define DEFINE_SIMPLE_ATTRIBUTE_SIGNED(__fops, __get, __set, __fmt)	\
+	DEFINE_SIMPLE_ATTRIBUTE_XSIGNED(__fops, __get, __set, __fmt, true)
+
 static inline __printf(1, 2)
 void __simple_attr_check_format(const char *fmt, ...)
 {
@@ -3161,6 +3167,8 @@ ssize_t simple_attr_read(struct file *file, char __user *buf,
 			 size_t len, loff_t *ppos);
 ssize_t simple_attr_write(struct file *file, const char __user *buf,
 			  size_t len, loff_t *ppos);
+ssize_t simple_attr_write_signed(struct file *file, const char __user *buf,
+				 size_t len, loff_t *ppos);
 
 struct ctl_table;
 int proc_nr_files(struct ctl_table *table, int write,



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux