Fix buffer overflow opportunities in AlertNotificationService & AlertNotificationClient.
This commit is contained in:
		
							parent
							
								
									4f9adb2372
								
							
						
					
					
						commit
						89e7033830
					
				@ -105,14 +105,25 @@ int AlertNotificationClient::OnDescriptorDiscoveryEventCallback(uint16_t connect
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void AlertNotificationClient::OnNotification(ble_gap_event *event) {
 | 
					void AlertNotificationClient::OnNotification(ble_gap_event *event) {
 | 
				
			||||||
  if(event->notify_rx.attr_handle == newAlertHandle) {
 | 
					  if(event->notify_rx.attr_handle == newAlertHandle) {
 | 
				
			||||||
    size_t notifSize = OS_MBUF_PKTLEN(event->notify_rx.om);
 | 
					    // TODO implement this with more memory safety (and constexpr)
 | 
				
			||||||
    uint8_t data[notifSize + 1];
 | 
					    static const size_t maxBufferSize{21};
 | 
				
			||||||
    data[notifSize] = '\0';
 | 
					    static const size_t maxMessageSize{18};
 | 
				
			||||||
    os_mbuf_copydata(event->notify_rx.om, 0, notifSize, data);
 | 
					    size_t bufferSize = min(OS_MBUF_PKTLEN(event->notify_rx.om), maxBufferSize);
 | 
				
			||||||
    char *s = (char *) &data[2];
 | 
					 | 
				
			||||||
    NRF_LOG_INFO("DATA : %s", s);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, notifSize + 1);
 | 
					    uint8_t data[bufferSize];
 | 
				
			||||||
 | 
					    os_mbuf_copydata(event->notify_rx.om, 0, bufferSize, data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *s = (char *) &data[3];
 | 
				
			||||||
 | 
					    auto messageSize = min(maxMessageSize, (bufferSize-3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < messageSize-1; i++) {
 | 
				
			||||||
 | 
					      if (s[i] == 0x00) {
 | 
				
			||||||
 | 
					        s[i] = 0x0A;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    s[messageSize-1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, messageSize);
 | 
				
			||||||
    systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification);
 | 
					    systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@
 | 
				
			|||||||
#include <SystemTask/SystemTask.h>
 | 
					#include <SystemTask/SystemTask.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "AlertNotificationService.h"
 | 
					#include "AlertNotificationService.h"
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace Pinetime::Controllers;
 | 
					using namespace Pinetime::Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,22 +56,25 @@ int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle
 | 
				
			|||||||
                                                    struct ble_gatt_access_ctxt *ctxt) {
 | 
					                                                    struct ble_gatt_access_ctxt *ctxt) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
 | 
					  if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
 | 
				
			||||||
        size_t notifSize = OS_MBUF_PKTLEN(ctxt->om);
 | 
					    // TODO implement this with more memory safety (and constexpr)
 | 
				
			||||||
        uint8_t data[notifSize + 1];
 | 
					    static const size_t maxBufferSize{21};
 | 
				
			||||||
        data[notifSize] = '\0';
 | 
					    static const size_t maxMessageSize{18};
 | 
				
			||||||
        os_mbuf_copydata(ctxt->om, 0, notifSize, data);
 | 
					    size_t bufferSize = min(OS_MBUF_PKTLEN(ctxt->om), maxBufferSize);
 | 
				
			||||||
        char *s = (char *) &data[3];
 | 
					 | 
				
			||||||
        NRF_LOG_INFO("DATA : %s", s);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for(int i = 0; i <= notifSize; i++)
 | 
					    uint8_t data[bufferSize];
 | 
				
			||||||
        {
 | 
					    os_mbuf_copydata(ctxt->om, 0, bufferSize, data);
 | 
				
			||||||
            if(s[i] == 0x00)
 | 
					
 | 
				
			||||||
            {
 | 
					    char *s = (char *) &data[3];
 | 
				
			||||||
 | 
					    auto messageSize = min(maxMessageSize, (bufferSize-3));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < messageSize-1; i++) {
 | 
				
			||||||
 | 
					      if (s[i] == 0x00) {
 | 
				
			||||||
        s[i] = 0x0A;
 | 
					        s[i] = 0x0A;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    s[messageSize-1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        m_notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, notifSize + 1);
 | 
					    m_notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, s, messageSize);
 | 
				
			||||||
    m_systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification);
 | 
					    m_systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -4,11 +4,12 @@
 | 
				
			|||||||
using namespace Pinetime::Controllers;
 | 
					using namespace Pinetime::Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NotificationManager::Push(Pinetime::Controllers::NotificationManager::Categories category,
 | 
					void NotificationManager::Push(Pinetime::Controllers::NotificationManager::Categories category,
 | 
				
			||||||
                                                      const char *message, uint8_t messageSize) {
 | 
					                                                      const char *message, uint8_t currentMessageSize) {
 | 
				
			||||||
  // TODO handle edge cases on read/write index
 | 
					  // TODO handle edge cases on read/write index
 | 
				
			||||||
 | 
					  auto checkedSize = std::min(currentMessageSize, uint8_t{18});
 | 
				
			||||||
  auto& notif = notifications[writeIndex];
 | 
					  auto& notif = notifications[writeIndex];
 | 
				
			||||||
  std::memcpy(notif.message.data(), message, messageSize);
 | 
					  std::memcpy(notif.message.data(), message, checkedSize);
 | 
				
			||||||
  notif.message[messageSize] = '\0';
 | 
					  notif.message[checkedSize] = '\0';
 | 
				
			||||||
  notif.category = category;
 | 
					  notif.category = category;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0;
 | 
					  writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0;
 | 
				
			||||||
 | 
				
			|||||||
@ -7,10 +7,10 @@ namespace Pinetime {
 | 
				
			|||||||
    class NotificationManager {
 | 
					    class NotificationManager {
 | 
				
			||||||
      public:
 | 
					      public:
 | 
				
			||||||
        enum class Categories {Unknown, SimpleAlert, Email, News, IncomingCall, MissedCall, Sms, VoiceMail, Schedule, HighProriotyAlert, InstantMessage };
 | 
					        enum class Categories {Unknown, SimpleAlert, Email, News, IncomingCall, MissedCall, Sms, VoiceMail, Schedule, HighProriotyAlert, InstantMessage };
 | 
				
			||||||
        static constexpr uint8_t MessageSize = 18;
 | 
					        static constexpr uint8_t MessageSize{18};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        struct Notification {
 | 
					        struct Notification {
 | 
				
			||||||
          std::array<char, MessageSize> message;
 | 
					          std::array<char, MessageSize+1> message;
 | 
				
			||||||
          Categories category = Categories::Unknown;
 | 
					          Categories category = Categories::Unknown;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user