Skip to content

Commit 695ba93

Browse files
committed
keys: skip FIFOs rather than blocking indefinitely
We can't open a FIFO and then check its type afterward, since opening for reading will block when the FIFO has no writers. Move file type check earlier in try_read_key_file().
1 parent db76cb4 commit 695ba93

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

src/errors.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ use error_chain::error_chain;
1717
error_chain! {
1818
foreign_links {
1919
Io(std::io::Error);
20+
Nix(nix::Error) #[cfg(test)];
2021
}
2122
}

src/keys.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
use std::fs::{read_dir, DirEntry, OpenOptions};
15+
use std::fs::{metadata, read_dir, DirEntry, OpenOptions};
1616
use std::io::{self, copy, Write};
1717
use std::os::unix::ffi::OsStringExt;
1818
use std::os::unix::fs::{MetadataExt, PermissionsExt};
@@ -108,22 +108,20 @@ fn try_read_key_file(
108108
bail!("{} is a dotfile, ignoring", ent.path().display());
109109
}
110110

111-
// check file permissions
111+
// check file type and permissions
112+
if !metadata(ent.path())
113+
.chain_err(|| format!("couldn't stat {}", ent.path().display()))?
114+
.is_file()
115+
{
116+
bail!("{} is not a file, ignoring", ent.path().display());
117+
}
112118
ensure_safe_permissions(&ent.path())?;
113119

114120
// open file
115121
let mut file = OpenOptions::new()
116122
.read(true)
117123
.open(ent.path())
118124
.chain_err(|| format!("opening {}", ent.path().display()))?;
119-
// avoid writing out the path comment if we have a directory
120-
if !file
121-
.metadata()
122-
.chain_err(|| format!("getting metadata for {}", ent.path().display()))?
123-
.is_file()
124-
{
125-
bail!("{} is not a file, ignoring", ent.path().display());
126-
}
127125

128126
// write comment with source path
129127
let safe_path = ent.path().to_string_lossy().replace("\n", "\u{fffd}");
@@ -150,6 +148,8 @@ mod tests {
150148
use std::io::Cursor;
151149
use std::os::unix::fs::symlink;
152150

151+
use nix::sys::stat;
152+
use nix::unistd::mkfifo;
153153
use tempfile::{Builder, TempDir};
154154

155155
fn make_file(path: &Path, contents: &str) -> Result<()> {
@@ -195,6 +195,8 @@ mod tests {
195195
symlink(&keydir.join("d"), &keydir.join("sd"))?;
196196
// dangling symlink
197197
symlink(&keydir.join("nx"), &keydir.join("snx"))?;
198+
// fifo
199+
mkfifo(&keydir.join("fifo"), stat::Mode::S_IRUSR)?;
198200

199201
Ok(dir)
200202
}
@@ -255,8 +257,9 @@ Caused by: Permission denied (os error 13)
255257
256258
Error: {dir}/d is not a file, ignoring
257259
258-
Error: opening {dir}/dnp
259-
Caused by: Permission denied (os error 13)
260+
Error: {dir}/dnp is not a file, ignoring
261+
262+
Error: {dir}/fifo is not a file, ignoring
260263
261264
Error: {dir}/sd is not a file, ignoring
262265

0 commit comments

Comments
 (0)