2010-11-18 32 views
5

Yazdığım bir Python uzantısı, tek bir donanım başlatma çağrısı yapmak için kök erişimi gerektirir. Uzantıdaki bu tek çağrı için tüm betiği root olarak çalıştırmamayı tercih ediyorum, bu nedenle kullanıcı ayrıcalıklarına düşmeden ve asıl senaryoyu çalıştırmadan önce bu başlatmayı yapmak için bir sarıcı yazmak istiyorum. Bu sarmalayıcı için niyetindeBir setuid sarıcı için dikkat edilmesi gerekenler

, sudo yoluyla yapılacaksa mesela

$ sudo devwrap python somescript.py 
I ( hata bir çift düzeltmek için güncellenmiş ) gibi bir şey düşündüğünü

:

int main(int argc, char * argv[]) 
{ 
    if(argc < 2) return 0; 

    int res = do_hardware_init(); 
    if(res != OK_VALUE) 
    { 
    // Print error message 
    return HW_ERR; 
    } 

    const char *sudo_uid = getenv("SUDO_UID"); 
    if(sudo_uid) 
    { 
     int real_uid = (int) strtol(sudo_uid, NULL, 0); 
     setuid(real_uid); 
    } 

    return execvp(argv[1], &argv[1]); // No return if successful 

} 

Yani var üç soru:

  1. bu aklı başında görünüyor? Genellikle * uid() çağrılarıyla uğraşmak zorunda değilim, bu yüzden normal tuzaklara aşina değilim. execvp çağrı da biraz tuhaf görünüyor, ama görebildiğim kadarıyla doğru yerde argümanlar var).
  2. execvp man page, "Ortam dizisine uygulama tarafından doğrudan erişilmemelidir" diyor " - bu getenv'u kötü bir fikir mi yapıyor?
  3. execvp daha iyi bir çağrı var mı, bu yüzden sudo devwrap somescript.py yapabilirsiniz ("piton" notu yokluğunu) daha aşağıda aklı başında bir

cevap

1
  1. Sıralama .... getenv() kullanma
  2. doğrudan environ dizi erişmiyor - yani temiz. environ dizisine doğrudan erişim, 'strcpy (buffer, environment [3]) `veya bunun gibi bir şey demektir. Script bir shebang (#!/usr/bin/env python belki) ile başlıyorsa
  3. , zaten istediğinizi yapabilirsiniz - somescript.py elbette, çalıştırılabilir olması gerekir.

İlk kısımda gördüğüm sorunlar, donanımın başlatılmasından kaynaklanan hataları nasıl ele aldığınıza bağlı olarak değişir. Aktarılan hata işleme, çıkmazsa, 'sudo' aracılığıyla çalıştırılmadığında çekirdek boşaltma (veya segfault) alabilirsiniz, çünkü boş bir işaretçi üzerinde strtol() çalıştırırsınız. do_hardware_init()'un kendisi hata durumunda çıkarsa, kullanıcı 'sudo' ortamını bozma yolu bulamazsa sorun olmaz. SUDO_UID makul bir şekilde ayarlanmadıysa, ortamı doğrulamanız ve bir hata ile çıkmanız gerektiğini düşünüyorum. Kök bu uzantıyı çalıştırmak ister mi?

SUDO_UID ortam değişkenini belirlediğini görmek için sudo belirtimine bakmadım - bunun üzerinde haklı olduğunuzu farz ediyorum.

bu yazarak kullanıcının olarak ne kadar uygun?

sudo devwrap ls 

O ls çalıştırır, sonra donanım başlatma yapar UID sıfırlar ve - çok zararlı, ama belki değil ne akılda olmadı muhtemelen. Önemi var? Bunu kontrol edebilir misin?

Bağımsız değişken sayısı ikiden küçükse, büyük olasılıkla bir hata çıkışı vermelisiniz, başarılı bir çıkış değil.


İnsanların 'sudo' aracılığıyla uzantıları çalıştırmasını şart koşmak çok sıra dışıdır.

Bunu başarmanın başka bir yolu olmadığından emin misiniz? Başlatmada gereklilikler nelerdir? Tüm süreçler için mi, yoksa süreç başına bir kere mi (zincirleme çok önemlidir)?


Sadece devwrap programını SUID root yapabilir misiniz? Daha sonra farklı UID sıfırlamak gerekir:

herhangi SGID-lik ve komutu yürütmeden önce, herhangi SUID-lik kaldırır
setgid(getgid()); 
setuid(getuid()); 

. Önemli hasarlar vermek oldukça zor. Program SGID olmadan yüklenirse, setgid() aramasının zorunlu olduğu açık değildir, ancak bu da hiçbir zarar vermez.

+0

* Bunu başarmanın başka bir yolu olmadığından emin misiniz? * Hayır, değilim, ama başka bir yol düşünemiyorum. Başlatma çağrısı kök olarak çalıştırılmazsa, başarısız olur, tam durur. Sanırım * bu işlemin – detly

+0

numaralı işleme göre gerekli olduğunu ... ama bu belgelenmemiş. Şaşırırdım, yine de bellek eşlemeli kontrol kayıtları gibi görünüyor. – detly

+0

Bunu kabul etmek için çok uzun süre için üzgünüm. Tavsiyeni almaya ve SUID yoluna gitmeye karar verdim. – detly

İlgili konular