Mengapa file dengan 400 izin terlihat dapat ditulis oleh root tetapi hanya dapat dibaca oleh pengguna?

10

Jika saya membuat file sebagai pengguna yang tidak berhak, dan mengubah mode izin menjadi 400, itu dilihat oleh pengguna itu sebagai hanya-baca, dengan benar:

$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro

Semua baik-baik saja.

Tapi kemudian root muncul:

# [ -w somefile ] && echo rw || echo ro
rw

Apa apaan? Tentu, root dapat menulis ke file read-only, tetapi seharusnya tidak membiasakannya: Praktik Terbaik cenderung mendikte bahwa saya harus dapat menguji bit izin tulis, dan jika tidak, maka ditetapkan seperti itu karena suatu alasan.

Saya rasa saya ingin memahami mengapa hal ini terjadi, dan bagaimana saya bisa mendapatkan kode pengembalian yang salah saat menguji file yang tidak memiliki bit tulis set?

Kaya
sumber
btw saya menggunakan keduanya RHEL6 ( 4.1.2(1)-release) dan RHEL7 ( 4.2.46(2)-release).
Kaya
16
"Praktik Terbaik cenderung mendikte bahwa saya harus bisa menguji bit izin menulis, dan jika tidak, maka ditetapkan seperti itu karena suatu alasan." - Sebenarnya, praktik terbaik adalah "jangan jalankan hal-hal sebagai root." Jika Anda menjalankan sebagai root, Anda telah memutuskan untuk melewati pemeriksaan izin. Menerapkan kembali pemeriksaan izin secara manual di userspace adalah resep bencana .
Kevin
@Kevin Baik untuk Anda jika Anda dapat menjalankan hal-hal yang tidak terjangkau. Ini untuk memanipulasi /etc/dhcp/dhcpd.conf, yang dimiliki oleh root. Saya menggunakan vendor yang disediakan dhcpd. Bencana total, ya? File diperiksa ke RCS, saya mengotomatisasi penggunaan rcsdiff, cidan cokarena kami memiliki operator yang perlu ... beroperasi. Pemeriksaan bit izin ( -w, seperti yang dijelaskan oleh test(1)) akan menjadi baris pertama kegagalan, bekerja atas dasar yang ci -umembuat file hanya dapat dibaca. Saya membuang itu dan langsung ke rcsdiff -qdan memeriksa $?. Tidak berbahaya dhcpd? Itu akan dimiliki oleh dhcpd.
Kaya
1
Ini adalah potensi bencana karena Anda sekarang memiliki dua implementasi pemeriksaan izin yang berbeda: satu di kernel dan satu di userspace. Lebih buruk lagi, implementasi itu bahkan tidak dimaksudkan untuk menghasilkan hasil yang identik, jadi Anda tidak bisa hanya mengujinya satu sama lain. Jadi sekarang Anda memiliki dua jalur untuk mengakses yang harus dikunci dan diamankan satu sama lain.
Kevin
@Kevin Tentu, mereka tidak menghasilkan hasil yang identik dan tidak dimaksudkan untuk (meskipun kekurangan detail dalam halaman manual), tapi saya secara eksplisit ingin memeriksa bit izin menulis ; dan halaman manual untuk bashdan testmembuat saya percaya itu untuk apa [ -w.
Kaya

Jawaban:

26

test -walias [ -wtidak memeriksa mode file. Ia memeriksa apakah itu dapat ditulisi. Untuk root, itu.

$ help test | grep '\-w'
  -w FILE        True if the file is writable by you.

Cara saya akan menguji akan melakukan perbandingan bitwise terhadap output stat(1)(" %a Hak akses dalam oktal").

(( 0$(stat -c %a somefile) & 0200 )) && echo rw || echo ro

Catatan subkulit $(...)perlu 0diawali sehingga output statditafsirkan sebagai oktal oleh (( ... )).

Patrick
sumber
Terima kasih sudah ringkas. Baik digunakan (( ... & ... )). Satu kesalahan ketik dikoreksi :-)
Kaya
Jadikan 3 ... Tidak ifdiperlukan, output oktal izin %atidak %d, dan (( ... ))perlu awalan 0untuk mengartikan output statsebagai oktal.
Kaya
@Patrick my man statmengatakan "% d nomor perangkat dalam desimal", tetapi yang kita inginkan adalah "hak akses", bukan? Maksud Anda tentang perlu 0 awalan dibuat dengan baik, tapi saya kira kita hanya perlu mengolahnya di sana :).
sourcejedi
2
stat -c 0%a...
sourcejedi
@sourcejedi ack, Anda benar. Untuk beberapa alasan saya berpikir% d adalah hak akses dalam desimal. Pulihkan hasil edit. terima kasih :-)
Patrick
30

Saya pikir Anda telah salah mengerti apa yang -wterjadi. Itu tidak memeriksa untuk melihat apakah file tersebut memiliki "Izin menulis", itu memeriksa untuk melihat apakah file tersebut dapat ditulisi oleh pengguna yang memohon .

Lebih khusus, itu panggilan access(2)atau sejenisnya.

misalnya jika skrip memiliki if [ -w /etc/shadow ]maka jika Anda menjalankan straceskrip Anda dapat melihat baris yang mirip

faccessat(AT_FDCWD, "/etc/shadow", W_OK)

Karena rootdapat menulis ke file maka mengembalikan 0.

mis. sebagai pengguna normal:

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = -1 EACCES (Permission denied)

Sebagai root

faccessat(AT_FDCWD, "/etc/shadow", W_OK) = 0

Ini, terlepas dari kenyataan yang /etc/shadowmemiliki izin 000pada mesin saya.

---------- 1 root root 4599 Jan 29 20:08 /etc/shadow

Sekarang apa yang ingin Anda lakukan menjadi menarik dan tidak begitu sederhana.

Jika Anda ingin memeriksa izin sederhana maka periksa lsoutput, atau panggilan statatau yang serupa. Tetapi sadari bahwa ACL dapat melewati izin ini secara berlebihan. Hanya karena file adalah izin 400 tidak menghentikannya agar tidak dapat ditulisi ...

Stephen Harris
sumber
Tidak, "kesalahpahaman" akan membaca halaman manual salah karena -w: test(1)eksplisit: "FILE ada dan izin menulis diberikan", bukan " file dapat ditulis oleh pengguna saat ini ". Apa-apa tentang mengesampingkan izin, atau ACL. bash(1)is cagey: "Benar jika file ada dan dapat ditulis ." ksh(1)membuat petunjuk halus terhadap shenanigans: "-w file // Benar, jika file ada dan dapat ditulis oleh proses saat ini ." zsh(1)menentang test(1), zshmisc(1)disebut sebagai ksh(1), dan zshexpn(1)merinci beberapa globbing berbasis izin yang menarik. csh(1)sangat meriah: "Akses tulis".
btw: Saya menerima jawaban Patrick, 1. karena Anda tidak cukup menjawab pertanyaan petunjuk: bagaimana saya bisa mendapatkan kode pengembalian yang salah ketika menguji file yang tidak memiliki set bit tulis? dan 2. karena anggapan utama yang jelek saya salah paham tentang halaman buku.
Kaya
3
@ Kaya Cara saya membaca ini, saya pikir komentar Anda terlihat sedikit aneh juga. Saya tidak mengatakan bahwa apa pun yang Anda tulis salah, hanya saja mungkin akan lebih baik jika diungkapkan dengan cara yang lebih sopan.
David Z
3
"Saya pikir Anda telah salah paham ..." tidak tajam. Namun tanggapan Anda, 100% snarky.
barbekyu
@ Kaya Juga, sementara halaman manual mungkin tidak sejernih kristal, Stephen telah menyatakan bahwa Anda mungkin telah "salah mengerti apa -w ", dan bukan apa yang dikatakan halaman manual , di mana yang pertama terlihat sebagai kasusnya, maka pertanyaannya
Sebi
1

Pengguna root dapat melakukannya sesuka hati, izin file "normal" tidak terbatas. Itu tidak akan langsung menjalankan file biasa tanpa izin eXecute, hanya untuk sedikit asuransi terhadap praktik target kaki.

vonbrand
sumber