Skip to content

espressif: refuse peer access to NO_ACCESS characteristics - #11558

Merged
dhalbert merged 1 commit into
adafruit:mainfrom
dhalbert:espressif-chr-no-access
Oct 12, 2026
Merged

dhalbert merged 1 commit into
adafruit:mainfrom
dhalbert:espressif-chr-no-access

Conversation

@dhalbert

Copy link
Copy Markdown
Collaborator

Diagnosis and code by Claude, reviewed by @dhalbert.

Bug

  • On espressif, a peer could read a characteristic declared READ with read_perm=Attribute.NO_ACCESS, and write one declared WRITE with write_perm=Attribute.NO_ACCESS.
  • nordic and zephyr-cp refuse these with ATT Read Not Permitted / Write Not Permitted.
  • Cause: NimBLE has no separate permission setting for a characteristic. Its BLE_GATT_CHR_F_READ and BLE_GATT_CHR_F_WRITE flags both declare the property and allow the access.
  • Characteristics that use NO_ACCESS without declaring the matching property, such as StreamIn in adafruit_ble, were not affected.

Fix

  • bleio_characteristic_access_cb() now returns BLE_ATT_ERR_READ_NOT_PERMITTED or BLE_ATT_ERR_WRITE_NOT_PERMITTED for NO_ACCESS.
  • The declared properties are unchanged, matching nordic and zephyr-cp.
  • Reads with no connection still succeed. NimBLE calls the callback that way to get the value for some notifications and indications.

Testing

Metro ESP32-S3 with this PR as peripheral:

Central Test Result
nRF54LM20 DK, zephyr-cp read/write NO_ACCESS characteristics read not permitted, write not permitted
nRF54LM20 DK, zephyr-cp ordinary read and write, over-length write to fixed_length unchanged
Linux host, bleak READ + NOTIFY characteristic with NO_ACCESS read permission properties still include read; read refused with Read Not Permitted; notifications received
nRF54LM20 DK, zephyr-cp ble_uart_echo_test.py / ble_uart_echo_client.py from the BLE library examples echoes received

NimBLE's READ and WRITE flags both declare a characteristic property and
allow the access, so a characteristic declared READ or WRITE with a
NO_ACCESS permission was fully readable or writable by a peer. Refuse
those reads and writes in the access callback, as nordic and zephyr-cp
do. Reads with no connection still succeed, so notifications that NimBLE
builds from the stored value still go out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dhalbert
dhalbert requested a review from mikeysklar October 12, 2026 00:41

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@dhalbert
dhalbert merged commit ef4302a into adafruit:main Oct 12, 2026
215 checks passed
@dhalbert
dhalbert deleted the espressif-chr-no-access branch October 12, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants