lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Thu, 11 Jan 2024 21:48:46 -0300
From: Guilherme Giácomo Simões <trintaeoitogc@...il.com>
To: linux-kernel@...r.kernel.org
Subject: new library

 Hi,

im a software developer and i have been studying and writing device drivers on an amateur basis.

I discovered that the float points are not easy to work in kernel land, for an obvious reason: Each CPU has a its owner way dealing with float points in FPU,

and somes CPUs don't have an FPU.

Although, with the kernel_fpu_begin/end, I can do arithmetic with float points....

But i wanted to show this in printk(), and unless im very mistaken this is not possible. What i can do is show a float point as an int number.

For ex: 12.34, changed to 1234. In dmesg output: [123432] 1234.


This is make never implemented, because probably dealing with floating points at the kernel land is extremely rare.

But, in my kernel fork I writed a library to change an integer number, to string with float point.

For ex: 1234 -> "12.34", and i show this in dmesg output: [09876] 12.34


I really don't know if this is useful, but here it is my initial sugestion is


include/linux/int2fpstr.h ++++++++


+ #ifndef _LINUX_INT2FPSTR_H
+ #define _LINUX_INT2FPSTR_H
+
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/string.h>
+
+ inline __kernel_size_t size_alloc(int number)
+ {
+     const int neg =  number < 0;
+     if(neg) number *= -1;
+
+     int ret = neg ? 2 : 1;
+     for(;
+         number;
+         number /= 10, ret++
+     );
+
+     return ret;
+ }
+
+ inline void int2fpstr(int number,
+         const int decimal_places, char* dest)
+ {
+     if(!number)    {
+         strncpy(dest, "0", 1);
+         return;
+     }
+
+     const __kernel_size_t size_alloc_n = size_alloc(number);
+     char* buffer = kmalloc(size_alloc_n, GFP_KERNEL);
+
+     int buf_index = size_alloc_n;
+     *(buffer + buf_index) = '\0';
+
+     int c_dec_places = 0;
+     int point_include = decimal_places < 1;
+
+     int neg = number < 0;
+     if(neg)
+         number *= -1;
+
+     for (; number && buf_index;
+         --buf_index, number /= 10)
+     {
+         c_dec_places++;
+         if (!point_include
+             && c_dec_places > decimal_places)
+         {
+             *(buffer + buf_index--) = '.';
+             point_include = 1;
+         }
+
+         *(buffer + buf_index) = "0123456789"[number % 10];
+     }
+
+     if(neg)
+         *(buffer + buf_index--) = '-';
+
+     strncpy(dest, &buffer[buf_index+1], size_alloc_n);
+ }
+
+ #endif



so, i create a unitest to library:

lib/int2fpstr_kunit.c ++++++

+ #include <kunit/test.h>
+ #include <linux/slab.h>
+ #include <linux/errno.h>
+ #include <linux/string.h>
+
+ #include <linux/int2fpstr.h>
+
+ static void should_return_2345_without_errors(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(2345), GFP_KERNEL);
+     int2fpstr(2345, 2, dest);
+     int ret = strncmp(dest, "23.45", 5);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_2_without_errors_and_float_point(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(2), GFP_KERNEL);
+     int2fpstr(2, 0, dest);
+     int ret = strncmp(dest, "2", 1);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_0_without_errors(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(1), GFP_KERNEL);
+     int2fpstr(0, 0, dest);
+     int ret = strncmp(dest, "0", 1);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_12_without_errors_and_float_point(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(12), GFP_KERNEL);
+     int2fpstr(12, 0, dest);
+     int ret = strncmp(dest, "12", 2);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_12_without_errors(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(12) + 1, GFP_KERNEL);
+     int2fpstr(-12, 0, dest);
+     int ret = strncmp(dest, "-12", 3);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static void should_return_125_without_errors(struct kunit *test)
+ {
+     char *dest = kmalloc(size_alloc(125), GFP_KERNEL);
+     int2fpstr(-125, 1, dest);
+     int ret = strncmp(dest, "-12.5", 5);
+     KUNIT_EXPECT_EQ(test, 0, ret);
+     kfree(dest);
+ }
+
+ static struct kunit_case int_to_fp_str_test_case[] = {
+     KUNIT_CASE(should_return_12_without_errors_and_float_point),
+     KUNIT_CASE(should_return_0_without_errors),
+     KUNIT_CASE(should_return_2_without_errors_and_float_point),
+     KUNIT_CASE(should_return_2345_without_errors),
+     KUNIT_CASE(should_return_12_without_errors),
+     KUNIT_CASE(should_return_125_without_errors),
+     { /* sentinel */ }
+ };
+
+ static struct kunit_suite int_to_fp_str_test = {
+     .name = "int2fpstr",
+     .test_cases = int_to_fp_str_test_case
+ };
+
+ kunit_test_suite(int_to_fp_str_test);
+
+ MODULE_AUTHOR("Guilherme Giacomo Simoes <trintaeoitogc@...il.com>");
+ MODULE_LICENSE("GPL");


This library can help the drivers writers, and (perhaps and very rarely) the subsystems writers. 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ