Closed gy741 closed 2 years ago
Seems unlikely. What does your /home/karas/minmea/minmea.h file look like around line 250? It should be:
static inline float minmea_tocoord(struct minmea_float f) { if (f->scale == 0) return NAN; int_least32_t degrees = f->value / (f->scale 100); int_least32_t minutes = f->value % (f->scale 100); return (float) degrees + (float) minutes / (60 f->scale); }
which includes a divide by zero check. Would be an interesting test for a fuzzer to see if it can still cause an FPE even with the divide by zero check.
Heath
On 20 Feb 2018, at 10:32 am, gy741 notifications@github.com wrote:
Hello.
I found a divide by zero bug in minmea.
Please confirm.
Thanks.
OS: CentOS 7 64bit Version: commit cd27e72 https://github.com/kosma/minmea/commit/cd27e72970cd50b46e9c95c1c0076a49c1ceaf33 PoC Download: FPE_minmea_tocoord.zip https://github.com/kosma/minmea/files/1738501/FPE_minmea_tocoord.zip ASAN:DEADLYSIGNAL
==15762==ERROR: AddressSanitizer: FPE on unknown address 0x000000513aa4 (pc 0x000000513aa4 bp 0x7ffefb6e80b0 sp 0x7ffefb6e80b0 T0)
0 0x513aa3 in minmea_tocoord /home/karas/minmea/minmea.h:250
#1 0x513c60 in main /home/karas/minmea/example.c:35 #2 0x7f92b2580c04 in __libc_start_main (/lib64/libc.so.6+0x21c04) #3 0x41ab5b in _start (/home/karas/minmea/example+0x41ab5b)
AddressSanitizer can not provide additional info. SUMMARY: AddressSanitizer: FPE /home/karas/minmea/minmea.h:250 in minmea_tocoord ==15762==ABORTING
[Acknowledgement] This work was supported by ICT R&D program of MSIP/IITP. [R7518-16-1001, Innovation hub for high Performance Computing]
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/kosma/minmea/issues/30, or mute the thread https://github.com/notifications/unsubscribe-auth/AFRsb59BZtdyOfbzhDpiOn5ou-_WzhRFks5tWgSPgaJpZM4SLOgY.
@hraftery
Hello,
I have not changed the minmea.h file.
So the contents of the file are the same.
I did some analysis.
In my opinion, if the scale value negative, can pass the condition.
Thanks.
/home/karas/minmea/minmea.h:250
static inline float minmea_tocoord(struct minmea_float *f)
{
if (f->scale == 0)
return NAN;
int_least32_t degrees = f->value / (f->scale * 100);
int_least32_t minutes = f->value % (f->scale * 100);
return (float) degrees + (float) minutes / (60 * f->scale);
}
GDB Log
Program received signal SIGFPE, Arithmetic exception.
0x00000000004009f8 in minmea_tocoord (f=0x7fffffffe2b4) at minmea.h:250
250 int_least32_t degrees = f->value / (f->scale * 100);
(gdb) p f->scale
$29 = -2147483648
(gdb) p f->value / (f->scale * 100)
Division by zero
(gdb) p f->value
$20 = 0
(gdb) p f->scale * 100
$21 = 0
#0 0x00000000004009f8 in minmea_tocoord (f=0x7fffffffe2b4) at minmea.h:250
degrees = 32767
minutes = -7484
#1 0x0000000000400bb5 in main () at example.c:35
frame = {time = {hours = -1, minutes = -1, seconds = -1, microseconds = -1}, valid = false, latitude = {value = 0, scale = -2147483648}, longitude = {value = 0, scale = 0}, speed = {value = 111,
scale = 1000}, course = {value = 4, scale = 1}, date = {day = -1, month = -1, year = -1}, variation = {value = 0, scale = 0}}
line = "$OSRMCGPNIT,,,.", '0' <repeats 21 times>, '1' <repeats 14 times>, ",,,,.111,4,,,,.11,,,.111,4,,,"
sample code
#include <stdio.h>
#include <stdint.h>
int main()
{
int b = 1;
int_least32_t scale = -2147483648;
if (scale == 0){
printf ("%d",b);
return 0;
}
int_least32_t degrees = scale * 100;
printf ("%d",degrees);
return 0;
}
Ah yes, f->scale is an integer. So overflow behaviour of f->scale * 100 is undefined (even if f->scale is positive). So yes, I agree, it looks like a bug.
I’m sure a pull request would be welcomed!
Heath
On 20 Feb 2018, at 1:49 pm, gy741 notifications@github.com wrote:
Hello,
I have not changed the minmea.h file.
So the contents of the file are the same.
I did some analysis.
In my opinion, if the scale value negative, can pass the condition.
Thanks.
static inline float minmea_tocoord(struct minmea_float f) { if (f->scale == 0) return NAN; int_least32_t degrees = f->value / (f->scale 100); int_least32_t minutes = f->value % (f->scale 100); return (float) degrees + (float) minutes / (60 f->scale); } GDB Log
Program received signal SIGFPE, Arithmetic exception. 0x00000000004009f8 in minmea_tocoord (f=0x7fffffffe2b4) at minmea.h:250 250 int_least32_t degrees = f->value / (f->scale 100); (gdb) p f->scale $29 = -2147483648 (gdb) p f->value / (f->scale 100) Division by zero (gdb) p f->value $20 = 0 (gdb) p f->scale * 100 $21 = 0
0 0x00000000004009f8 in minmea_tocoord (f=0x7fffffffe2b4) at minmea.h:250
degrees = 32767 minutes = -7484
1 0x0000000000400bb5 in main () at example.c:35
frame = {time = {hours = -1, minutes = -1, seconds = -1, microseconds = -1}, valid = false, latitude = {value = 0, scale = -2147483648}, longitude = {value = 0, scale = 0}, speed = {value = 111, scale = 1000}, course = {value = 4, scale = 1}, date = {day = -1, month = -1, year = -1}, variation = {value = 0, scale = 0}} line = "$OSRMCGPNIT,,,.", '0' <repeats 21 times>, '1' <repeats 14 times>, ",,,,.111,4,,,,.11,,,.111,4,,,"
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/kosma/minmea/issues/30#issuecomment-366852427, or mute the thread https://github.com/notifications/unsubscribe-auth/AFRsb_XJ87p3dCCwoKjcuL6wCcXRbyOcks5tWjKdgaJpZM4SLOgY.
@hraftery
Hello,
I have sent a pull request.
Please let me know if there is a better patch method.
Pull : #31
hmm.... In my opinion, it is an insecure patch.
Thanks.
@hraftery
Hello,
I modified the source code again.
What do you think of this source code?
Thanks.
static inline float minmea_tocoord(struct minmea_float *f)
{
if (f->scale == 0)
return NAN;
+ if (f->scale > (INT_LEAST32_MAX / 100))
+ return NAN;
+ if (f->scale < (INT_LEAST32_MIN / 100))
+ return NAN;
int_least32_t degrees = f->value / (f->scale * 100);
int_least32_t minutes = f->value % (f->scale * 100);
return (float) degrees + (float) minutes / (60 * f->scale);
}
Looks pretty good. I guess it’s now up to kosma to pull it!
On 22 Feb 2018, at 12:52 pm, gy741 notifications@github.com wrote:
@hraftery https://github.com/hraftery Hello,
I modified the source code again.
What do you think of this source?
Thanks.
static inline float minmea_tocoord(struct minmea_float *f) { if (f->scale == 0) return NAN;
- if (f->scale > (INT_LEAST32_MAX / 100))
- return NAN;
- if (f->scale < (INT_LEAST32_MIN / 100))
- return NAN; int_least32_t degrees = f->value / (f->scale 100); int_least32_t minutes = f->value % (f->scale 100); return (float) degrees + (float) minutes / (60 * f->scale); } — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kosma/minmea/issues/30#issuecomment-367540783, or mute the thread https://github.com/notifications/unsubscribe-auth/AFRsb6FQ25HCw6OvTFfqEFmKeJInPKjZks5tXMhSgaJpZM4SLOgY.
Hello,
thank you for confirmation.
I have sent a pull request.
Pull : #32
Thanks.
That's a good catch! I need to have another look at the code to see if there's some way to avoid the extra if-check by changing math. I should resolve this in a few days.
@kosma I'm guessing you've dropped the ball on this one?
Should minmea_float.scale be an unsigned value?
Sorry for the delay, merged the PR. @matonga can you reopen if there is still an issue and/or feel free to open a PR to resolve?
Hello.
I found a divide by zero bug in minmea.
Please confirm.
Thanks.
OS: CentOS 7 64bit Version: commit cd27e72970cd50b46e9c95c1c0076a49c1ceaf33 PoC Download: FPE_minmea_tocoord.zip
================= [Acknowledgement] This work was supported by ICT R&D program of MSIP/IITP. [R7518-16-1001, Innovation hub for high Performance Computing]