2010-11-18 38 views
5

Tiện ích mở rộng Python mà tôi đã viết yêu cầu quyền truy cập gốc để thực hiện cuộc gọi khởi tạo phần cứng đơn. Tôi không muốn chạy toàn bộ kịch bản như là root chỉ cho một cuộc gọi này trong phần mở rộng của tôi, vì vậy tôi muốn viết một wrapper để làm điều này initialisation trước khi rơi vào quyền người dùng và chạy kịch bản thực tế.Cân nhắc về trình bao bọc setuid

tôi có ý định cho wrapper này để được chạy qua sudo, ví dụ:

$ sudo devwrap python somescript.py 

Tôi đã xem xét một cái gì đó tương tự (cập nhật để sửa chữa một vài lỗi):

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 

} 

Vì vậy, tôi có ba câu hỏi:

  1. Điều này có vẻ lành mạnh không? Tôi thường không cần phải gây rối với các cuộc gọi * uid(), vì vậy tôi không quen với những cạm bẫy thông thường. Cuộc gọi execvp cũng có vẻ kỳ lạ một chút, nhưng theo như tôi có thể thấy nó có đối số ở đúng nơi).
  2. Trang execvp trang người đàn ông nói rằng "Mảng môi trường không được truy cập trực tiếp bởi ứng dụng" - điều này có làm cho ý tưởng không đúng là getenv không?
  3. Có một cuộc gọi tốt hơn so với execvp, vì vậy tôi có thể làm sudo devwrap somescript.py (lưu ý sự vắng mặt của "trăn")

Trả lời

1
  1. Sắp xếp của lành mạnh ... chi tiết dưới đây.
  2. Sử dụng getenv() không truy cập trực tiếp vào mảng environ - sạch sẽ. Truy cập mảng environ trực tiếp có nghĩa là 'strcpy (buffer, environ [3]) `hoặc một cái gì đó tương tự.
  3. Nếu kịch bản bắt đầu bằng một shebang (#!/usr/bin/env python, có lẽ), bạn có thể làm những gì bạn muốn - tất nhiên, somescript.py phải thực thi được.

Các vấn đề tôi thấy với phần đầu tiên phụ thuộc vào cách bạn xử lý lỗi từ quá trình khởi tạo phần cứng. Nếu việc xử lý lỗi bị bỏ qua không thoát, thì bạn có thể lấy một kết xuất lõi (hoặc segfault) khi không chạy qua 'sudo' vì bạn chạy strtol() trên một con trỏ rỗng. Nếu do_hardware_init() thoát khỏi sự cố, không có vấn đề gì, trừ khi người dùng tìm cách phá hoại môi trường khỏi 'sudo'. Tôi thực sự nghĩ rằng bạn nên xác nhận môi trường và thoát ra với một lỗi nếu SUDO_UID không được thiết lập một cách hợp lý. Gốc có muốn chạy tiện ích mở rộng này không?

Tôi đã không xem xét đặc điểm kỹ thuật của sudo để thấy rằng nó đặt biến môi trường SUDO_UID - Tôi giả sử bạn đã đúng về điều đó.

Chi nhánh của người dùng nhập này là gì?

sudo devwrap ls 

Nó khởi tạo phần cứng, reset UID, và sau đó chạy ls - có lẽ không phải là quá nguy hiểm, nhưng có lẽ không phải những gì bạn có trong tâm trí. Điều đó có quan trọng không? Bạn có thể kiểm soát điều đó không?

Nếu số đối số nhỏ hơn hai, có thể bạn nên thoát lỗi, chứ không phải thoát thành công.


Rất độc đáo để yêu cầu mọi người chạy tiện ích mở rộng qua 'sudo'.

Bạn có chắc chắn không có cách nào khác để đạt được nó? Các yêu cầu về khởi tạo là gì? Nó được thực hiện một lần cho tất cả các quá trình, hoặc một lần cho mỗi quá trình (vì vậy chuỗi là rất quan trọng)?


Bạn có thể đơn giản làm cho chương trình devwrap SUID root không? Sau đó, bạn sẽ cần phải đặt lại UID theo cách khác:

setgid(getgid()); 
setuid(getuid()); 

Việc này loại bỏ mọi SGID và bất kỳ SUID nào trước khi thực thi lệnh. Thật khó để gây ra thiệt hại đáng kể. Không rõ ràng rằng cuộc gọi setgid() là bắt buộc nếu chương trình được cài đặt mà không có SGID, nhưng nó cũng không gây hại.

+0

* Bạn có chắc chắn không có cách nào khác để đạt được nó? * Không, tôi không, nhưng tôi không thể nghĩ ra cách khác. Nếu cuộc gọi khởi tạo không chạy như gốc, nó không thành công, dừng hoàn toàn. Tôi không * nghĩ * rằng nó được yêu cầu cho mỗi quá trình – detly

+0

... nhưng đó không phải là tài liệu. Tôi sẽ ngạc nhiên, mặc dù, nó chỉ có vẻ là bộ nhớ kiểm soát đăng ký bản đồ. – detly

+0

Xin lỗi vì đã quá lâu để chấp nhận điều này. Tôi đã quyết định nhận lời khuyên của bạn và đi theo lộ trình SUID. – detly

Các vấn đề liên quan