[PATCH] Fix undefined behaviour

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

 



Another day, another sanitizer.

After fixing issues reported by -fsanitize=address yesterday, I gave -fsanitize=undefined a try. The GCC documentation points to the clang documentation: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

The issues related to cControl::player were tricky. In the end, I figured it out after setting UBSAN_OPTIONS=print_stacktrace=1 and setting a breakpoint on _Unwind_Backtrace(). The name of the reporting function in my system was __ubsan_handle_dynamic_type_cache_miss(), nothing about "vptr". Also, the diagnostics was misleadingly pointing to the body of the constructor, and not the initializer list where a data member was being assigned to before the base class had been initialized.

The -fsanitize=undefined in clang might report more things.

Next I may give -fsanitize=thread a try.

GCC does not implement -fsanitize=memory (checking for the use of uninitialized memory) at all. It will require clang and libc++ (not libstdc++) and that all libraries except libc are built with -fsanitize=memory. If you are familiar with Valgrind's default memcheck tool, it is roughly comparable to the combination of -fsanitize=address and -fsanitize=memory.

	Marko
>From b69ff7105d4bb8d933f0214f34b103fda8e8b155 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= <marko.makela@xxxxxx>
Date: Sun, 4 Dec 2022 13:42:57 +0200
Subject: [PATCH] Fix GCC 8.3.0 -fsanitize=undefined

sections.c:183:30: runtime error: variable length array bound evaluates to non-positive value 0
device.c:251:31: runtime error: variable length array bound evaluates to non-positive value 0
osd.h:301:37: runtime error: signed integer overflow: -2147483648 - 2147483647 cannot be represented in type 'int'
osd.h:301:37: runtime error: signed integer overflow: -2147483647 - 2147483647 cannot be represented in type 'int'
transfer.c:71:11: runtime error: member access within address 0x020f0428 which does not point to an object of type 'cTransferControl'
dvbplayer.c:984:11: runtime error: member access within address 0x02a388d0 which does not point to an object of type 'cDvbPlayerControl'
---
 device.c    | 2 +-
 dvbplayer.c | 3 ++-
 font.c      | 3 ++-
 osd.h       | 4 ++--
 sections.c  | 2 +-
 transfer.c  | 3 ++-
 6 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/device.c b/device.c
index 4e987389..a770aa90 100644
--- a/device.c
+++ b/device.c
@@ -248,7 +248,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
 {
   // Collect the current priorities of all CAM slots that can decrypt the channel:
   int NumCamSlots = CamSlots.Count();
-  int SlotPriority[NumCamSlots];
+  int SlotPriority[std::max(NumCamSlots, 1)];
   int NumUsableSlots = 0;
   bool InternalCamNeeded = false;
   if (Channel->Ca() >= CA_ENCRYPTED_MIN) {
diff --git a/dvbplayer.c b/dvbplayer.c
index 2ee846b6..72bc46ad 100644
--- a/dvbplayer.c
+++ b/dvbplayer.c
@@ -981,8 +981,9 @@ bool cDvbPlayer::GetReplayMode(bool &Play, bool &Forward, int &Speed)
 // --- cDvbPlayerControl -----------------------------------------------------
 
 cDvbPlayerControl::cDvbPlayerControl(const char *FileName, bool PauseLive)
-:cControl(player = new cDvbPlayer(FileName, PauseLive))
+:cControl(new cDvbPlayer(FileName, PauseLive))
 {
+  player = static_cast<cDvbPlayer*>(cControl::player);
 }
 
 cDvbPlayerControl::~cDvbPlayerControl()
diff --git a/font.c b/font.c
index 8b37798c..c78b1a15 100644
--- a/font.c
+++ b/font.c
@@ -74,7 +74,8 @@ cGlyph::cGlyph(uint CharCode, FT_GlyphSlotRec_ *GlyphData)
   rows = GlyphData->bitmap.rows;
   pitch = GlyphData->bitmap.pitch;
   bitmap = MALLOC(uchar, rows * pitch);
-  memcpy(bitmap, GlyphData->bitmap.buffer, rows * pitch);
+  if (int bytes = rows * pitch)
+    memcpy(bitmap, GlyphData->bitmap.buffer, bytes);
 }
 
 cGlyph::~cGlyph()
diff --git a/osd.h b/osd.h
index 77722662..7a293321 100644
--- a/osd.h
+++ b/osd.h
@@ -298,8 +298,8 @@ public:
 struct tArea {
   int x1, y1, x2, y2;
   int bpp;
-  int Width(void) const { return x2 - x1 + 1; }
-  int Height(void) const { return y2 - y1 + 1; }
+  int Width(void) const { return x2 < 0 ? 0 : x2 - x1 + 1; }
+  int Height(void) const { return y2 < 0 ? 0 : y2 - y1 + 1; }
   bool Intersects(const tArea &Area) const { return !(x2 < Area.x1 || x1 > Area.x2 || y2 < Area.y1 || y1 > Area.y2); }
   };
 
diff --git a/sections.c b/sections.c
index 51a2823c..4d90b19c 100644
--- a/sections.c
+++ b/sections.c
@@ -180,7 +180,7 @@ void cSectionHandler::Action(void)
            startFilters = false;
            }
         int NumFilters = filterHandles.Count();
-        pollfd pfd[NumFilters];
+        pollfd pfd[std::max(NumFilters, 1)];
         for (cFilterHandle *fh = filterHandles.First(); fh; fh = filterHandles.Next(fh)) {
             int i = fh->Index();
             pfd[i].fd = fh->handle;
diff --git a/transfer.c b/transfer.c
index 88931e58..b888910a 100644
--- a/transfer.c
+++ b/transfer.c
@@ -68,8 +68,9 @@ void cTransfer::Receive(const uchar *Data, int Length)
 cDevice *cTransferControl::receiverDevice = NULL;
 
 cTransferControl::cTransferControl(cDevice *ReceiverDevice, const cChannel *Channel)
-:cControl(transfer = new cTransfer(Channel), true)
+:cControl(new cTransfer(Channel), true)
 {
+  transfer = static_cast<cTransfer*>(player);
   ReceiverDevice->AttachReceiver(transfer);
   receiverDevice = ReceiverDevice;
 }
-- 
2.38.1

_______________________________________________
vdr mailing list
vdr@xxxxxxxxxxx
https://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

[Index of Archives]     [Linux Media]     [Asterisk]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Big List of Linux Books]     [Fedora Users]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux