#1009654 rpi.gpio-common: udev rule gets truncated for long device paths

Package:
rpi.gpio-common
Source:
rpi.gpio
Submitter:
Zack Yancey
Date:
2026-10-07 07:39:03 UTC
Severity:
important
Tags:
#1009654#5
Date:
2022-04-13 16:35:58 UTC
From:
To:
Dear Maintainer,

There's an issue with a udev rule messing up some device permissions: when I plug a device in through a usb hub, the entire PCI bus gets its permissions changed and can't be read anymore.

The problem is in /usr/lib/udev/rules.d/60-rpi.gpio-common.rules, line 3:

```
SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="dialout", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value ; chmod 660 /sys%p/active_low /sys%p/direction /sys%p/edge /sys%p/value'"
```

enabling debug logging for udev, I see this when the device gets plugged in:

```
Mar 31 13:52:16 raspberrypi systemd-udevd[1553]: gpiochip2: /usr/lib/udev/rules.d/60-rpi.gpio-common.rules:3 Running PROGRAM '/bin/sh -c 'chown root:dialout /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/active_low /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/direction /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/edge /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/value ; chmod 660 /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/active_low /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/direction /sys/devices/platform/scb/fd500000.pcie'
Mar 31 13:52:16 raspberrypi systemd-udevd[1553]: gpiochip2: Starting '/bin/sh -c 'chown root:dialout /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/active_low /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/direction /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/edge /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/value ; chmod 660 /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/active_low /sys/devices/platform/scb/fd500000.pcie/pci0000:00/0000:00:00.0/0000:01:00.0/usb1/1-1/1-1.2/1-1.2.4/1-1.2.4.4/1-1.2.4.4.1/1-1.2.4.4.1:1.0/gpiochip2/direction /sys/devices/platform/scb/fd500000.pcie'
```

The command that's executed doesn't match the command that's in the rules file--it gets truncated at 1023 characters. In this case, that happens to be right on a directory name, so the chmod 660 gets applied to /sys/devices/platform/scb/fd500000.pcie instead of a specific gpio file.

I was able to work around the bug by splitting up that last line:

```
SUBSYSTEM=="bcm2835-gpiomem", KERNEL=="gpiomem", GROUP="dialout", MODE="0660"
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys/class/gpio/export /sys/class/gpio/unexport ; chmod 220 /sys/class/gpio/export /sys/class/gpio/unexport'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/active_low'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/direction'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/edge'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chown root:dialout /sys%p/value'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chmod 660 /sys%p/active_low'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chmod 660 /sys%p/direction'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chmod 660 /sys%p/edge'"
SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add", PROGRAM="/bin/sh -c 'chmod 660 /sys%p/value'"
```

That lets %p get a lot larger before we start running into the apparent 1023-character limit for PROGRAM= values. There may be a better way to do this, for example moving all the chown/chmod commands to a script.

I believe this bug could also be the cause of #1001469, as the symptom looks similar.

Thanks,
Zack Yancey

#1009654#10
Date:
2026-10-07 07:37:57 UTC
From:
To:
Attached is a patch fixing the udev rule truncation.

Root cause: the PROGRAM= value in debian/rpi.gpio-common.udev's third
rule substitutes %p eight separate times (four in the chown arguments,
four in the chmod arguments). udev performs this substitution into the
rule text before invoking /bin/sh, so a deeply nested device path (e.g.
reached through a chain of USB hubs) gets multiplied by 8x in the final
command string, which is what overruns udev's ~1023-character internal
limit on PROGRAM values and produces the truncation described in the
original report.

Fix: substitute %p once into a shell variable ($p, escaped as $$p so
udev itself doesn't try to interpret it as one of its own $-prefixed
specifiers) and reuse that variable for all eight references instead of
re-substituting %p each time. This cuts the multiplier from 8x to 1x.

Verified:
- udevadm verify reports the patched rule file as syntactically valid
- Simulated against a realistic deeply-nested USB-hub sysfs path: the
  original rule produces a 1515-character command (over the limit,
  reproducing the reported truncation); the patched rule produces a
  310-character command for the same path (comfortably under it)
- Patch applies cleanly against a fresh pristine 0.7.1~a4-1.2 source tree

The reporter's own suggested alternative (splitting into multiple
shorter PROGRAM rules) would also work but only reduces the multiplier
by a constant factor rather than addressing why the substitution
happens repeatedly in the first place; this patch is a smaller diff
with a larger safety margin.

Changes:
- debian/rpi.gpio-common.udev (one line changed)
- debian/changelog