[BUG] bluez: Buffer overflow in emulator/bthost.c (bthost_set_pin_code)

From: 侯朋朋 <hidden>
Date: 2026-03-11 02:44:58

Dear BlueZ Developers,

  I am reporting a buffer overflow (intra-object overflow) discovered in the BlueZ emulator code within emulator/bthost.c. This issue allows a caller of the emulator API to
  overwrite internal state of the bthost structure due to missing bounds checking.

  Vulnerability Analysis

  In emulator/bthost.c, the function bthost_set_pin_code() copies a PIN code into a fixed-size buffer within the struct bthost. However, it does not verify if the provided
  pin_len exceeds the destination buffer's capacity.

  Relevant Structure Definition:

   1 struct bthost {
   2     ...
   3     uint8_t pin[16];       // Fixed size: 16 bytes
   4     uint8_t pin_len;       // Adjacent member
   5     uint8_t io_capability; // Adjacent member
   6     uint8_t auth_req;      // Adjacent member
   7     ...
   8 };

  Vulnerable Function (src/emulator/bthost.c:4064):

   1 void bthost_set_pin_code(struct bthost *bthost, const uint8_t *pin,
   2                             uint8_t pin_len)
   3 {
   4     // pin_len is uint8_t (0-255), bthost->pin is only 16 bytes.
   5     // NO check: if (pin_len > sizeof(bthost->pin))
   6     memcpy(bthost->pin, pin, pin_len);
   7     bthost->pin_len = pin_len;
   8 }

  Impact

  If an external test tool or an automated test case passes a pin_len greater than 16 (up to 255) to this function:
   1. Memory Corruption: memcpy will overflow the bthost->pin array.
   2. State Corruption: It will overwrite adjacent members in the struct bthost, specifically pin_len, io_capability, and auth_req.
   3. Undefined Behavior: This corruption can lead to unpredictable behavior in the emulator or crashes during the execution of test suites.

  Suggested Fix

  I recommend adding a bounds check to ensure the pin_len does not exceed the size of the pin array:


   1 void bthost_set_pin_code(struct bthost *bthost, const uint8_t *pin,
   2                             uint8_t pin_len)
   3 {
   4     if (pin_len > sizeof(bthost->pin))
   5         pin_len = sizeof(bthost->pin);
   6
   7     memcpy(bthost->pin, pin, pin_len);
   8     bthost->pin_len = pin_len;
   9 }

  I have verified this issue using a reproduction case within the emulator environment, confirming that provided PINs longer than 16 bytes immediately corrupt the
  io_capability field.

Best regards,
Pengpeng Hou
pengpeng@iscas.ac.cn
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help