Fhem und HiPi, Zugriffsrechte /dev/mem

Begonnen von tatus1969, 09 Januar 2014, 14:35:48

Vorheriges Thema - Nächstes Thema

tatus1969

die Kombination dieser beiden Programme ermöglicht es Fhem, auf vielseitige Weise die an die GPIO, den SPI oder den I2C angeschlossenen Chips anzusteuern. Die meisten Funktionen funktionieren mit normalen Zugriffsrechten, weil entsprechende Gerätetreiber Teil von HiPi sind. Es gibt jedoch Funktionen in HiPi, die Zugriff auf /dev/mem benötigen (in meinem Fall brauchte ich die Möglichkeit, einen 500kHz-Takt an GPIO4 auszugeben). Das Problem hierbei ist:

HiPi muss für den Zugriff auf /dev/mem mit Rootrechten ausgeführt werden (Erweitern der Zugriffsrechte auf /dev/mem genügt nicht, der Kernel prüft zusätzlich, ob der Anforderer tatsächlich 'root' ist).

Ein Start per "sudo perl fhem.pl fhem.cfg" funktioniert jedoch nicht, weil Fhem beim Programmstart selbsttätig auf den Benutzer "fhem" überwechselt und dadurch die dazugehörigen eingeschränkten Rechte übernimmt...

Man kann natürlich jetzt beginnen und den entsprechenden Codeteil aus fhem.pl herauslöschen, oder den Benutzer "fhem" löschen, doch für ein Programm mit Webinterface, welches bestenfalls von jedem Internetcafe der Welt aus bedient werden kann, ist das sicher keine besonders gute Idee.

Hier ein Lösungsvorschlag:

Fhem könnte vor der Abgabe der Rootrechte die Initialize-Funktion von 99_myUtils aufrufen. Diese könnte dadurch mit den nötigen Rechten HiPi initialisieren und zur späteren Verwendung einen Zeiger/Handle in einer statischen Variable ablegen. Fhem kann jetzt seine Rootrechte abgeben. Das Spannende daran ist, dass HiPi sie jetzt auch nicht mehr braucht, weil das Memory Mapping auf /dev/mem ja bereits passiert ist und erhalten bleibt.

Siehe auch: http://forum.fhem.de/index.php/topic,18515.0.html

rudolfkoenig

Der Vorschlag gefaellt mir nicht, da es meiner Ansicht nach nur ein Hack bzw. ein Workaround fuer ein Linux-Treiber-Bug ist: wenn ich Schreibrechte auf eine Datei habe, dann muss ich auch schreiben koennen.

Man kann es auch anders loesen:
Unix-User fhem in fhem2 umbenennen, uid merken
define changePerm notify global:INITIALIZED { use POSIX qw(setuid);; setuid(<fhem2-uid>) }


Idealerweise gehoert setuid() in ein FHEM-HiPi-Modul.

P.S.: Wenn jemand in meiner Wohnung die Tuer aufmachen kann, meinen Garten unter Wasser setzen kann, usw., dann ist es mir echt egal, wenn er auf dem RPi noch zusaetzlich Root-Rechte hat.

tatus1969

Zitat von: rudolfkoenig am 09 Januar 2014, 15:05:00
nur ein Hack bzw. ein Workaround fuer ein Linux-Treiber-Bug
Das ist kein Bug, sondern ein zusätzlicher Zugriffsschutz, zumal /dev/mem ja ein potentielles Hacker-Scheunentor ist. Das ist soweit ich recherchieren konnte in jedem modernen Linux so realisiert.

Zitat von: rudolfkoenig am 09 Januar 2014, 15:05:00
Unix-User fhem in fhem2 umbenennen, uid merken
define changePerm notify global:INITIALIZED { use POSIX qw(setuid);; setuid(<fhem2-uid>) }

Gute Idee, danke!

Zitat von: rudolfkoenig am 09 Januar 2014, 15:05:00
Idealerweise gehoert setuid() in ein FHEM-HiPi-Modul.
Hab nachgeschaut, sowas gibt es tatsächlich... HiPi::Utils::drop_permissions_name($username,$groupname);

Zitat von: rudolfkoenig am 09 Januar 2014, 15:05:00
Wenn jemand in meiner Wohnung die Tuer aufmachen kann, meinen Garten unter Wasser setzen kann, usw., dann ist es mir echt egal, wenn er auf dem RPi noch zusaetzlich Root-Rechte hat.
Bei mir könnte er zum Glück nur die Heizung abschalten. Was wenn dieser jemand eher an Datenklau interessiert ist, und über den RPi Zugriff auf das restliche Heimnetzwerk bekommt?

betateilchen

Zitat von: tatus1969 am 09 Januar 2014, 15:53:57Hab nachgeschaut, sowas gibt es tatsächlich... HiPi::Utils::drop_permissions_name($username,$groupname);

das hatte ich Dir doch gestern schon geschickt ;)
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

tatus1969

Zitat von: betateilchen am 09 Januar 2014, 15:57:18
das hatte ich Dir doch gestern schon geschickt ;)
tja, manchmal zündet der Funke später :-)

tatus1969

Ich habe jetzt das folgende Vorgehen erfolgreich umgesetzt.

1. fhem-User umbenennen, damit Fhem nicht selbsttätig die Rootrechte abgibt: "sudo usermod -l fhem1 fhem"

2. folgende 99_myUtils.pm (dieses Beispiel erzeugt einen 500kHz-Takt an GPIO4 durch Aufruf von {setclk} durch Verwendung der BCM8235-Library und Zugriff via /dev/mem):

package main;
use strict;
use warnings;
use POSIX;

use HiPi::BCM2835 qw( :registers );
use HiPi::Constant qw( :raspberry );

my $bcm;

sub
myUtils_Initialize($$)
{
  my ($hash) = @_;

  my $bcm  = HiPi::BCM2835->new();

  HiPi::Utils::drop_permissions_name("fhem1","fhem1");
}

sub
setclk
{
  $bcm->peri_write( BCM2835_CLOCK_BASE | 0x70, 0x5A000001 );
  $bcm->delay( 10 );
  $bcm->peri_write( BCM2835_CLOCK_BASE | 0x74, 0x5A002000 | (39 << 12) );
  $bcm->peri_write( BCM2835_CLOCK_BASE | 0x70, 0x5A000011 );
  $bcm->get_pin( RPI_PAD1_PIN_7 )->mode( RPI_PINMODE_ALT0 );
}
1;


Dieses Verfahren hat allerdings einen Nachteil. Arbeitet man in Fhem über das Webinterface an der Datei 99_myUtils.pm und speichert diese dann, so wird erneut deren Initialize-Sub gerufen, dieses Mal jedoch ohne Rootrechte und daher erfolglos. Ein Neustart von fhem mit den passenden Rechten bringt das wieder in Ordnung.

Frank