Skip to content

Commit a46ee4c

Browse files
Copilot0xrinegade
andcommitted
Fix security and architectural issues in installer
Co-authored-by: 0xrinegade <[email protected]>
1 parent 17ac66f commit a46ee4c

File tree

4 files changed

+207
-30
lines changed

4 files changed

+207
-30
lines changed

applications/gparted.desktop

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Type=Application
88
Categories=System;Filesystem;
99
Keywords=partition;disk;filesystem;
1010
StartupNotify=true
11-
X-GNOME-UsesNotifications=true
11+
X-GNOME-UsesNotifications=true

applications/osvmarchi-installer.desktop

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Type=Application
88
Categories=System;Setup;
99
Keywords=install;disk;partition;installer;
1010
StartupNotify=true
11-
X-GNOME-UsesNotifications=true
11+
X-GNOME-UsesNotifications=true

applications/osvmarchi-partition-manager.desktop

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Type=Application
88
Categories=System;Filesystem;
99
Keywords=partition;disk;gparted;cfdisk;fdisk;
1010
StartupNotify=true
11-
X-GNOME-UsesNotifications=true
11+
X-GNOME-UsesNotifications=true

bin/osvmarchi-install

Lines changed: 204 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,38 @@
55

66
set -euo pipefail
77

8+
# Configuration file for installation state
9+
INSTALL_CONFIG_FILE="/tmp/osvmarchi-install.conf"
10+
11+
# Save installation state
12+
save_install_state() {
13+
local key="$1"
14+
local value="$2"
15+
16+
# Create config file if it doesn't exist
17+
[[ ! -f "$INSTALL_CONFIG_FILE" ]] && touch "$INSTALL_CONFIG_FILE"
18+
19+
# Remove existing key if present
20+
sed -i "/^${key}=/d" "$INSTALL_CONFIG_FILE"
21+
22+
# Add new key=value
23+
echo "${key}=${value}" >> "$INSTALL_CONFIG_FILE"
24+
}
25+
26+
# Load installation state
27+
load_install_state() {
28+
local key="$1"
29+
30+
if [[ -f "$INSTALL_CONFIG_FILE" ]]; then
31+
grep "^${key}=" "$INSTALL_CONFIG_FILE" | cut -d'=' -f2-
32+
fi
33+
}
34+
35+
# Clean up configuration
36+
cleanup_install_state() {
37+
[[ -f "$INSTALL_CONFIG_FILE" ]] && rm -f "$INSTALL_CONFIG_FILE"
38+
}
39+
840
# Colors for output
941
RED='\033[0;31m'
1042
GREEN='\033[0;32m'
@@ -76,8 +108,21 @@ check_prerequisites() {
76108

77109
if [[ ${#missing_tools[@]} -gt 0 ]]; then
78110
log_error "Missing required tools: ${missing_tools[*]}"
79-
log_info "Installing missing tools..."
80-
pacman -Sy --noconfirm "${missing_tools[@]}"
111+
log_warning "The following tools need to be installed: ${missing_tools[*]}"
112+
113+
if gum confirm "Install missing tools now? (Requires internet connection)"; then
114+
log_info "Installing missing tools..."
115+
if ! pacman -Sy --noconfirm "${missing_tools[@]}"; then
116+
log_error "Failed to install required tools"
117+
log_info "Please install manually: pacman -S ${missing_tools[*]}"
118+
exit 1
119+
fi
120+
log_success "Tools installed successfully"
121+
else
122+
log_error "Cannot proceed without required tools"
123+
log_info "Please install manually: pacman -S ${missing_tools[*]}"
124+
exit 1
125+
fi
81126
fi
82127
}
83128

@@ -203,8 +248,25 @@ automatic_partition() {
203248
exit 1
204249
fi
205250

206-
# Unmount any existing partitions
207-
umount "${disk}"* 2>/dev/null || true
251+
# Safely unmount any existing partitions
252+
log_info "Checking for mounted partitions on $disk..."
253+
local mounted_parts
254+
mapfile -t mounted_parts < <(findmnt -rno TARGET,SOURCE | grep "^/.*$disk" | awk '{print $1}' | sort -r)
255+
256+
if [[ ${#mounted_parts[@]} -gt 0 ]]; then
257+
log_warning "Found mounted partitions, unmounting safely..."
258+
for mount_point in "${mounted_parts[@]}"; do
259+
log_info "Unmounting $mount_point"
260+
if ! umount "$mount_point" 2>/dev/null; then
261+
log_warning "Normal unmount failed, forcing unmount of $mount_point"
262+
if ! umount -f "$mount_point" 2>/dev/null; then
263+
log_error "Failed to unmount $mount_point, disk may be busy"
264+
log_info "Please manually unmount all partitions on $disk before continuing"
265+
exit 1
266+
fi
267+
fi
268+
done
269+
fi
208270

209271
# Wipe disk
210272
log_info "Wiping disk $disk..."
@@ -239,9 +301,9 @@ automatic_partition() {
239301
log_info "Formatting root partition..."
240302
mkfs.ext4 -L "OSVMarchi" "$root_part"
241303

242-
# Export partition variables for later use
243-
export OSVMARCHI_BOOT_PART="$boot_part"
244-
export OSVMARCHI_ROOT_PART="$root_part"
304+
# Save partition information to config file
305+
save_install_state "OSVMARCHI_BOOT_PART" "$boot_part"
306+
save_install_state "OSVMARCHI_ROOT_PART" "$root_part"
245307

246308
log_success "Automatic partitioning complete"
247309
}
@@ -282,28 +344,107 @@ manual_partition() {
282344
exit 1
283345
fi
284346

285-
# Export partition variables for later use
286-
export OSVMARCHI_BOOT_PART="$boot_part"
287-
export OSVMARCHI_ROOT_PART="$root_part"
347+
# Validate EFI System Partition
348+
log_info "Validating EFI System Partition..."
349+
local boot_fstype
350+
boot_fstype=$(lsblk -no FSTYPE "$boot_part" 2>/dev/null || echo "unknown")
351+
352+
if [[ "$boot_fstype" != "vfat" ]]; then
353+
log_warning "EFI partition ($boot_part) is not FAT32 (found: $boot_fstype)"
354+
if gum confirm "Format $boot_part as FAT32?"; then
355+
log_info "Formatting EFI partition as FAT32..."
356+
mkfs.fat -F 32 -n "EFI" "$boot_part"
357+
else
358+
log_error "EFI partition must be FAT32 for UEFI boot"
359+
exit 1
360+
fi
361+
fi
362+
363+
# Check EFI System Partition flag using sgdisk
364+
if command -v sgdisk &>/dev/null; then
365+
local part_num
366+
part_num=$(echo "$boot_part" | grep -o '[0-9]*$')
367+
local disk_path
368+
disk_path=$(echo "$boot_part" | sed 's/[p]*[0-9]*$//')
369+
370+
if ! sgdisk -i "$part_num" "$disk_path" | grep -q "EF00"; then
371+
log_warning "EFI partition does not have ESP (EF00) type code"
372+
if gum confirm "Set ESP type code on $boot_part?"; then
373+
sgdisk -t "${part_num}:EF00" "$disk_path"
374+
log_success "ESP type code set"
375+
else
376+
log_warning "Continuing without ESP type code (may cause boot issues)"
377+
fi
378+
fi
379+
fi
380+
381+
# Validate root partition filesystem
382+
log_info "Validating root partition..."
383+
local root_fstype
384+
root_fstype=$(lsblk -no FSTYPE "$root_part" 2>/dev/null || echo "unknown")
288385

289-
log_success "Manual partitioning complete"
290-
log_info "Boot partition: $boot_part"
291-
log_info "Root partition: $root_part"
386+
if [[ "$root_fstype" == "unknown" || "$root_fstype" == "" ]]; then
387+
log_warning "Root partition ($root_part) appears unformatted"
388+
local fs_choice
389+
fs_choice=$(echo -e "ext4\nbtrfs" | gum choose --header="Choose filesystem for root partition:")
390+
391+
case "$fs_choice" in
392+
"ext4")
393+
log_info "Formatting root partition as ext4..."
394+
mkfs.ext4 -L "OSVMarchi" "$root_part"
395+
;;
396+
"btrfs")
397+
log_info "Formatting root partition as btrfs..."
398+
mkfs.btrfs -L "OSVMarchi" "$root_part"
399+
;;
400+
esac
401+
elif [[ "$root_fstype" != "ext4" && "$root_fstype" != "btrfs" && "$root_fstype" != "xfs" ]]; then
402+
log_warning "Root partition filesystem ($root_fstype) may not be suitable"
403+
if ! gum confirm "Continue with $root_fstype filesystem?"; then
404+
exit 1
405+
fi
406+
fi
407+
408+
# Save partition information to config file
409+
save_install_state "OSVMARCHI_BOOT_PART" "$boot_part"
410+
save_install_state "OSVMARCHI_ROOT_PART" "$root_part"
411+
412+
log_success "Manual partitioning complete and validated"
413+
log_info "Boot partition: $boot_part ($boot_fstype)"
414+
log_info "Root partition: $root_part ($root_fstype)"
292415
}
293416

294417
# Mount partitions and install base system
295418
install_base_system() {
296-
local root_part="$OSVMARCHI_ROOT_PART"
297-
local boot_part="$OSVMARCHI_BOOT_PART"
419+
local root_part
420+
local boot_part
421+
422+
# Load partition information from config
423+
root_part=$(load_install_state "OSVMARCHI_ROOT_PART")
424+
boot_part=$(load_install_state "OSVMARCHI_BOOT_PART")
425+
426+
if [[ -z "$root_part" || -z "$boot_part" ]]; then
427+
log_error "Partition information not found in configuration"
428+
exit 1
429+
fi
298430

299431
log_info "Mounting partitions..."
432+
log_info "Root: $root_part -> /mnt"
433+
log_info "Boot: $boot_part -> /mnt/boot"
300434

301435
# Mount root
302-
mount "$root_part" /mnt
436+
if ! mount "$root_part" /mnt; then
437+
log_error "Failed to mount root partition $root_part"
438+
exit 1
439+
fi
303440

304441
# Create and mount boot
305442
mkdir -p /mnt/boot
306-
mount "$boot_part" /mnt/boot
443+
if ! mount "$boot_part" /mnt/boot; then
444+
log_error "Failed to mount boot partition $boot_part"
445+
umount /mnt 2>/dev/null || true
446+
exit 1
447+
fi
307448

308449
log_info "Installing base Arch Linux system..."
309450

@@ -323,8 +464,17 @@ install_base_system() {
323464
configure_base_system() {
324465
log_info "Configuring base system..."
325466

326-
# Chroot configuration script
327-
cat > /mnt/configure_system.sh << 'EOF'
467+
# Get partition information
468+
local root_part
469+
root_part=$(load_install_state "OSVMARCHI_ROOT_PART")
470+
471+
if [[ -z "$root_part" ]]; then
472+
log_error "Root partition information not found"
473+
exit 1
474+
fi
475+
476+
# Create configuration script that will run in chroot
477+
cat > /mnt/configure_system.sh << EOF
328478
#!/bin/bash
329479
set -e
330480
@@ -353,13 +503,16 @@ systemctl enable NetworkManager
353503
# Install and configure bootloader (systemd-boot)
354504
bootctl install
355505
506+
# Get root partition UUID for bootloader
507+
ROOT_PARTUUID=\$(blkid -s PARTUUID -o value $root_part)
508+
356509
# Create bootloader entry
357510
mkdir -p /boot/loader/entries
358511
cat > /boot/loader/entries/arch.conf << EOL
359512
title OSVMarchi
360513
linux /vmlinuz-linux
361514
initrd /initramfs-linux.img
362-
options root=PARTUUID=$(blkid -s PARTUUID -o value ${OSVMARCHI_ROOT_PART}) rw quiet splash
515+
options root=PARTUUID=\$ROOT_PARTUUID rw quiet splash
363516
EOL
364517
365518
cat > /boot/loader/loader.conf << EOL
@@ -371,15 +524,28 @@ EOL
371524
372525
# Create user
373526
useradd -m -G wheel -s /bin/bash user
374-
echo "user:user" | chpasswd
375527
376-
# Configure sudo
377-
echo "%wheel ALL=(ALL:ALL) ALL" >> /etc/sudoers
528+
# Disable root password and lock account for security
529+
passwd -l root
530+
531+
# Configure sudo using proper sudoers.d approach
532+
cat > /etc/sudoers.d/wheel << EOL
533+
# Allow wheel group to use sudo
534+
%wheel ALL=(ALL:ALL) ALL
535+
EOL
378536
379-
# Set root password
380-
echo "root:root" | chpasswd
537+
# Set secure permissions on sudoers.d file
538+
chmod 0440 /etc/sudoers.d/wheel
539+
540+
# Force password change on first login for user
541+
chage -d 0 user
542+
543+
# Set a temporary password that must be changed
544+
echo "user:changeme" | chpasswd
381545
382546
echo "Base system configuration complete"
547+
echo "SECURITY: User password must be changed on first login"
548+
echo "SECURITY: Root account is locked for security"
383549
EOF
384550

385551
# Make script executable and run it
@@ -442,11 +608,22 @@ main() {
442608

443609
# Cleanup
444610
log_info "Cleaning up..."
445-
umount -R /mnt
611+
612+
# Safely unmount all mounted filesystems
613+
if mountpoint -q /mnt/boot; then
614+
umount /mnt/boot
615+
fi
616+
if mountpoint -q /mnt; then
617+
umount /mnt
618+
fi
619+
620+
# Clean up temporary configuration
621+
cleanup_install_state
446622

447623
log_success "OSVMarchi installation completed successfully!"
448624
log_info "You can now reboot into your new OSVMarchi system"
449-
log_info "Default login: user/user (change password after first login)"
625+
log_warning "IMPORTANT: User password is 'changeme' and MUST be changed on first login"
626+
log_info "Root account is locked for security - use sudo for administrative tasks"
450627

451628
if gum confirm "Reboot now?"; then
452629
reboot

0 commit comments

Comments
 (0)