Commit 93b98639 authored by sudoBash418's avatar sudoBash418 Committed by Will Fancher
Browse files

make-initrd-ng: Restore stripped file permissions

Previously, all initrd ELFs would be made *world-writable*.

This commit sets the write bit for the file owner exclusively, and
removes it when done. It also sets the umask so that files don't
implicitly become writable for other users by mistake.

Fixes: https://github.com/NixOS/nixpkgs/security/advisories/GHSA-m7pq-h9p4-8rr4


Reported-By: default avatarsudoBash418 <sudobash418@gmail.com>
parent afdd737c
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4

[[package]]
name = "eyre"
@@ -35,6 +35,12 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"

[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"

[[package]]
name = "log"
version = "0.4.21"
@@ -47,6 +53,7 @@ version = "0.1.0"
dependencies = [
 "eyre",
 "goblin",
 "libc",
 "serde",
 "serde_json",
]
+1 −0
Original line number Diff line number Diff line
@@ -9,5 +9,6 @@ edition = "2018"
[dependencies]
eyre = "0.6.8"
goblin = "0.5.0"
libc = "0.2.171"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
+14 −3
Original line number Diff line number Diff line
@@ -5,9 +5,12 @@ use std::fs;
use std::hash::Hash;
use std::iter::FromIterator;
use std::os::unix;
use std::os::unix::fs::PermissionsExt;
use std::path::{Component, Path, PathBuf};
use std::process::Command;

use libc::umask;

use eyre::Context;
use goblin::{elf::Elf, Object};
use serde::Deserialize;
@@ -191,9 +194,9 @@ fn copy_file<
        let mut permissions = fs::metadata(&target)
            .wrap_err_with(|| format!("failed to get metadata for {:?}", target))?
            .permissions();
        permissions.set_readonly(false);
        fs::set_permissions(&target, permissions)
            .wrap_err_with(|| format!("failed to set readonly flag to false for {:?}", target))?;
        permissions.set_mode(permissions.mode() | 0o200);
        fs::set_permissions(&target, permissions.clone())
            .wrap_err_with(|| format!("failed to set read-write permissions for {:?}", target))?;

        // Strip further than normal
        if let Ok(strip) = env::var("STRIP") {
@@ -207,6 +210,11 @@ fn copy_file<
                println!("{:?} was not successfully stripped.", OsStr::new(&target));
            }
        }

        // Remove writable permissions
        permissions.set_mode(permissions.mode() ^ 0o222);
        fs::set_permissions(&target, permissions)
            .wrap_err_with(|| format!("failed to remove writable permissions for {:?}", target))?;
    };

    Ok(())
@@ -335,6 +343,9 @@ fn main() -> eyre::Result<()> {
    let output = &args[2];
    let out_path = Path::new(output);

    // The files we create should not be writable.
    unsafe { umask(0o022) };

    let mut queue = NonRepeatingQueue::<StorePath>::new();

    for sp in input {