Python Portioスクリプトを一般ユーザーとして実行します。ルートアクセスは必要ありません。

Python Portioスクリプトを一般ユーザーとして実行します。ルートアクセスは必要ありません。

通常のユーザーとしてrootスクリプトを実行する危険があることを知っていますが、この場合は選択肢がなく、私が何をするのかはコンピュータによって異なります。 GPIOポートを備えた小型ボードコンピュータがあり、出力の1つを使用してシャットダウンラインを切り替えてデバイスをリセットする必要があります。部品が正常に動作し、デバイスが期待どおりにリセットされます。

私の問題は、デバイスをリセットするためにPythonスクリプトを作成しましたが、うまくいきましたが、rootまたは「Sudoプログラム名、パスワードの入力」で実行する必要があることです。ただし、root権限なしで通常のユーザーで作業するには必要です。つまり、一般ユーザーを追加しましたが、何をしてもスクリプトを実行できませんでした。

sudoerファイルにユーザーを追加しようとしましたが、うまくいかず完全に無視されました。権限を変更し、SUIDビットと私が考えることができるすべてを設定しましたが、まだrootパスワードを求めます。動作する唯一の方法は、「ユーザーとグループ」を開き、ユーザーをSudoグループに追加することです。ただし、ユーザーは私のデフォルトの管理者ユーザーと同じであるため、望ましくないプログラムにアクセスできます。それは私が望むものではありません。このユーザーがアクセスできるもの(単一のスクリプトやプログラムなど)を何とか制限したいと思います。

他の人がドライバを書く必要があることを提案したことがありますが、その方法や意味が正確に何であるかよくわかりません。私はLinuxを使ったことがありますが、この分野の専門家だとは思いません。これを行う方法を知っている人はいますか?

ベストアンサー1

解決策が見つかりましたここ

あなたが望むのは、必要なポートへのアクセスのみを許可する信頼できるI / OイネーブラをCで書いてから、次のものを使用することです。execvp()呼び出し側のアドレス空間でスクリプトを実行します。その後、uid rootをコンパイルされたI / Oアクティベーターに設定できます。

以下は、上記のソースコードを適用したいくつかのサンプルコードです(書き込みに問題のないアドレスブロックを使用する必要があります)。

#include <stdio.h>
#include <stdlib.h>
#include <sys/io.h>

#define DESIRED_PORT    0x300
#define NUM_BYTES       8

int main(int argc, char*argv[])
{
    if (argc < 2) {
        printf("Error: no target program specified.\n");
        exit(1);
    }

    if (ioperm(DESIRED_PORT, NUM_BYTES, 1)) {
        printf("Error: couldn't set port permissions.\n");
        exit(1);
    }

    // Set uid to current user's id before executing the script
    setgid(getgid());
    setuid(getuid());

    if (execvp(argv[1], &argv[1]) < 0) {
        printf("Error: target program execution error.\n");
        exit(1);
    }
}

名前を io_enable.c と指定し、uid ルートをコンパイルして設定します。

$ gcc io_enable.c -o io_enable
$ sudo chown root io_enable
$ sudo chmod u+s io_enable

次に、次のPythonスクリプトを使用してテストできます。

#!/usr/bin/python
import portio

ADDR = 0x300

fd = open('/tmp/portio.log', 'w')

for i in range(10):
    portio.outb(i, ADDR)
    fd.write('Wrote %d, read %d.\n' % (i, portio.inb(ADDR)))

fd.close()

名前をio_test.pyとして指定し、次のように実行しました。

$ ./io_enable python io_test.py

うまくいくようです。

$ cat /tmp/portio.log
Wrote 0, read 0.
Wrote 1, read 1.
Wrote 2, read 2.
Wrote 3, read 3.
Wrote 4, read 4.
Wrote 5, read 5.
Wrote 6, read 6.
Wrote 7, read 7.
Wrote 8, read 8.
Wrote 9, read 9.

おすすめ記事