Có một tập tin luôn tồn tại và người dùng 'bình thường' không thể giữ nó?


14

Tôi cần điều này cho một bài kiểm tra đơn vị. Có một chức năng mà lstat trên đường dẫn tệp được truyền dưới dạng tham số của nó. Tôi phải kích hoạt đường dẫn mã lstatbị lỗi (vì phạm vi bảo hiểm mã phải đạt 90%)

Thử nghiệm chỉ có thể chạy dưới một người dùng duy nhất, do đó tôi tự hỏi liệu có tệp nào trong Ubuntu luôn tồn tại không, nhưng người dùng bình thường không có quyền truy cập đọc vào nó hoặc vào thư mục của nó. (Vì vậy, lstatsẽ thất bại trên nó trừ khi được thực thi như root.)

Một tệp không tồn tại không phải là một giải pháp, bởi vì có một đường dẫn mã riêng cho điều đó, mà tôi đã kích hoạt.

EDIT: Thiếu quyền truy cập đọc vào tệp chỉ là không đủ. Với điều đó lstatvẫn có thể được thực thi. Tôi đã có thể kích hoạt nó (trên máy cục bộ của tôi, nơi tôi có quyền truy cập root), bằng cách tạo một thư mục trong / root và một tệp trong đó. Và thiết lập quyền 700 trên thư mục. Vì vậy, tôi đang tìm kiếm một tập tin trong một thư mục chỉ có thể truy cập bằng root.


6
IMHO/etc/shadow
Romeo Ninov

3
Bạn không thể giả sử sự tồn tại của bất kỳ tệp nào, bởi vì chương trình của bạn có thể chạy trong một không gian tên chroot hoặc riêng biệt. Nếu giả sử rằng / Proc được gắn kết là OK và init không có gì đặc biệt, thì /proc/1/fd/0nên làm.
mosvy 25/2/19

1
@mosvy Cảm ơn rằng hoạt động trên máy cục bộ của tôi. Hmm, sau đó tôi cũng sẽ thử nó trên QA và Staging pool.
Ngọa mèo

2
Tại sao bạn buộc mã kiểm tra của mình vào một hương vị đặc biệt của HĐH khi bạn chỉ có thể tạo một tệp vứt đi và xóa quyền truy cập đọc của riêng bạn vào nó?
Kilian Foth

4
Tôi tranh luận rằng nó không thực sự là một bài kiểm tra đơn vị một khi nó bắt đầu tùy thuộc vào một hệ thống tập tin thực, chứ không phải bị chế giễu.
Toby Speight

Câu trả lời:


21

Trên các hệ thống Linux hiện đại, bạn sẽ có thể sử dụng /proc/1/fdinfo/0(thông tin cho bộ mô tả tệp 1 (stdout) của quá trình id 1 ( inittrong không gian tên gốc pid sẽ chạy như root)).

Bạn có thể tìm thấy một danh sách với (như một người dùng bình thường):

sudo find /etc /dev /sys /proc -type f -print0 |
  perl -l -0ne 'print unless lstat'

(xóa -type fnếu bạn không muốn giới hạn các tệp thông thường).

/var/cache/ldconfig/aux-cachelà một ứng cử viên tiềm năng khác nếu bạn chỉ cần xem xét các hệ thống Ubuntu. Nó nên hoạt động trên hầu hết các hệ thống GNU khi /var/cache/ldconfigđược tạo đọc + write + có thể tìm kiếm để root chỉ bằng ldconfiglệnh đi kèm với libc GNU.


1
Cảm ơn! Nếu /proc/1/fdinfo/0hoạt động trên Ubuntu 16.04 và 18.04, thế là quá đủ.
Ngọa mèo

1
Việc sử dụng /proc/1/fdinfo/0không nhất thiết phải hoạt động trong một thùng chứa (ví dụ: thùng chứa Docker) và thường kiểm tra đơn vị được chạy trong các thùng chứa như vậy trong CI.
Philipp Wendler

@PhilippWendler, tôi đã đề cập đến không gian tên gốc pid rồi. OP không hỏi về các thùng chứa mà về các tệp được đảm bảo có trong bố cục hệ thống tệp của hệ thống Ubuntu. Vì các thùng chứa có thể chứa bất kỳ bố cục tệp và thư mục, câu hỏi đó không thể trả lời được ở đó.
Stéphane Chazelas

12

Nhìn vào trang man lstat (2), bạn có thể có được một chút cảm hứng về các trường hợp có thể khiến nó không thành công với các lỗi khác ngoài ENOENT (tệp không tồn tại.)

Rõ ràng nhất là:

EACCES Quyền tìm kiếm bị từ chối đối với một trong các thư mục trong tiền tố đường dẫn của đường dẫn .

Vì vậy, bạn cần một thư mục bạn không thể tìm kiếm từ.

Có, bạn có thể tìm kiếm một cái đã có trong hệ thống của bạn (có lẽ /var/lib/privatenếu nó tồn tại?) Nhưng bạn cũng có thể tự tạo một cái, với tương đương:

$ mkdir myprivatedir
$ touch myprivatedir/myunreachablefile
$ chmod 0 myprivatedir
$ ls -l myprivatedir/myunreachablefile

Hoạt động lstat (2) sẽ thất bại với EACCES tại đây. (Xóa tất cả các quyền khỏi thư mục đảm bảo rằng. Có lẽ bạn thậm chí không cần nhiều như vậy và chmod -xloại bỏ các quyền thực thi là đủ, vì các quyền thực thi trên một thư mục là cần thiết để truy cập các tệp trong đó.)

Có một cách sáng tạo khác để làm cho lstat (2) thất bại, nhìn vào trang người đàn ông của nó:

ENOTDIR Một thành phần của tiền tố đường dẫn của đường dẫn không phải là một thư mục.

Vì vậy, cố gắng truy cập một tệp như /etc/passwd/nonexistentsẽ gây ra lỗi này, một lần nữa khác với ENOENT ("Không có tệp hoặc thư mục như vậy") và có thể phù hợp với nhu cầu của bạn.

Một số khác là:

Con đường ENAMETOOLONG quá dài.

Nhưng bạn có thể cần một cái tên thực sự dài cho cái này (tôi tin rằng 4.096 byte là giới hạn điển hình, nhưng hệ thống / hệ thống tệp của bạn có thể có tên dài hơn.)

Cuối cùng, thật khó để biết liệu bất kỳ thứ nào trong số này sẽ thực sự hữu ích cho bạn. Bạn nói rằng bạn muốn một cái gì đó không kích hoạt kịch bản "tập tin không tồn tại". Mặc dù thông thường có nghĩa là lỗi ENOENT, trong thực tế, nhiều kiểm tra cấp cao hơn sẽ đơn giản diễn giải bất kỳ lỗi nào từ lstat (2) là "không tồn tại". Ví dụ test -ehoặc tương đương [ -e ...]từ shell có thể chỉ đơn giản là diễn giải tất cả các điều trên là "không tồn tại", đặc biệt vì nó không có cách nào tốt để trả về một thông báo lỗi khác và không trả về lỗi sẽ ám chỉ tệp tồn tại, đó là điều chắc chắn nhất


@StephaneChazelas Điểm tuyệt vời! Cập nhật.
filbranden

6

Bạn có thể findtự mình làm được.

Sử dụng /etc- thư mục tệp cấu hình làm điểm bắt đầu:

sudo find /etc -type f -perm 0400 -user root

Trên hệ thống của tôi, điều này không trả lại bất cứ điều gì.

Bạn có thể là một nhóm ít hạn chế hơn và cho phép root(chỉ người dùng rootnên là thành viên của nhóm root) và xem xét sự cho phép của 440:

sudo find /etc -perm 0440 -user root -group root

Trên hệ thống của tôi, điều này trả về:

/etc/sudoers.d/README
/etc/sudoers

Biên tập:

Dựa trên chỉnh sửa của bạn, bạn đang tìm kiếm một thư mục không có đủ quyền cho người dùng gọi để ngăn chặn danh sách thư mục:

sudo find / -perm o-rwx -type d -user root -group root 

Ở đây tôi đang tìm các thư mục ( -type d) thiếu các bit perm đọc-ghi-thực thi cho người khác ( o-rwx) và được sở hữu bởi root:root.

Về mặt kỹ thuật, chỉ cần sự vắng mặt của xbit exec ( ) sẽ ngăn chặn một danh sách thư mục ( lstat(2)) trên thư mục.

Trong đầu ra tôi đã tìm thấy /run/systemd/inaccessible/trên hệ thống dựa trên Systemd init của mình.

Về tập tin trong /proc, /sys, /dev:

  • Các hệ thống tệp này là FS ảo tức là chúng nằm trên bộ nhớ, không phải trên đĩa

  • Nếu bạn có kế hoạch dựa vào /proc, hãy sử dụng /proc/1/tức là dựa vào một cái gì đó theo PID 1, chứ không phải bất kỳ bộ PID nào sau này để có độ tin cậy / tính nhất quán vì các bộ PID (quy trình) sau này không được đảm bảo tồn tại.


Cảm ơn, tôi nghĩ rằng câu hỏi của tôi là sai. Tôi vẫn có thể lstat các tập tin mà không cần đọc quyền truy cập vào chúng. Có lẽ quyền truy cập vào thư mục phải được giới hạn? (Tôi đã sửa đổi tiêu đề)
Ngọa mèo vào

Cảm ơn. Với find / -type d -perm 0400 -user roottôi đã tìm thấy thư mục /proc/20/map_files/, nếu tôi đề cập đến một tên tệp được tạo trong thư mục /proc/20/map_files/asdasdđó, thì nó luôn thất bại. Có phải thư mục đó luôn tồn tại trên Ubuntu?
Ngọa mèo

@CrouchingKitten, các thư mục trong /proc/1/có thể an toàn hơn, vì init luôn tồn tại. Nhưng đó proc, không phải là một hệ thống tập tin thông thường, trong trường hợp nó quan trọng.
ilkkachu

Cảm ơn tôi đã đưa ra một upvote, nhưng chấp nhận câu trả lời khác, bởi vì anh ấy nói rằng nó được đảm bảo /proc/1/fdinfo/0hoạt động trên Ubuntus hiện đại.
Ngọa mèo

-perm o-rwxgiống như -perm 0, tất cả đều bắt đầu với. Ở đây, bạn muốn ! -perm -1.
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.