You are here

Planet GNOME

Subscribe to Feed Planet GNOME
Planet GNOME - https://planet.gnome.org/
Përditësimi: 1 ditë 13 orë më parë

Michael Catanzaro: How to Get Hacked by North Korea

Hën, 29/07/2024 - 11:18md

Good news: exploiting memory safety vulnerabilities is becoming more difficult. Traditional security vulnerabilities will remain a serious threat, but attackers prefer to take the path of least resistance, and nowadays that is to attack developers rather than the software itself. Once the attackers control your computer, they can attempt to perform a supply chain attack and insert backdoors into your software, compromising all of your users at once.

If you’re a software developer, it’s time to start focusing on the possibility that attackers will target you personally. Yes, you. If you use Linux, macOS, or Windows, take a moment to check your home directory for a hidden .n2 folder. If it exists, alas! You have been hacked by the North Koreans. (Future malware campaigns will presumably be more stealthy than this.)

Attackers who target developers are currently employing two common strategies:

  • Fake job interview: you’re applying to job postings and the recruiter asks you to solve a programming problem of some sort, which involves installing software from NPM (or PyPI, or another language ecosystem’s package manager).
  • Fake debugging request: you receive a bug report and the reporter helpfully provides a script for reproducing the bug. The script may have dependencies on packages in NPM (or PyPI, or another language ecosystem’s package manager) to make it harder to notice that it’s malware. I saw a hopefully innocent bug report that was indistinguishable from such an attack just last week.

But of course you would never execute such a script without auditing the dependencies thoroughly! (Insert eyeroll emoji here.)

By now, most of us are hopefully already aware of typosquatting attacks, and the high risk that untrustworthy programming language packages may be malicious. But you might not have considered that attackers might target you personally. Exercise caution whenever somebody asks you to install packages from these sources. Take the time to start a virtual machine before running the code. (An isolated podman container probably works too?) Remember, attackers will target the path of least resistance. Virtualization or containerization raises the bar considerably, and the attacker will probably move along to an easier target.

Alberto Ruiz: Booting with Rust: Chapter 2

Pre, 26/07/2024 - 5:06md

In a previous post I gave the context for my pet project ieee1275-rs, it is a framework to build bootable ELF payloads on Open Firmware (IEEE 1275). OF is a standard developed by Sun for SPARC and aimed to provide a standardized firmware interface that was rich and nice to work with, it was later adopted by IBM, Apple for POWER and even the OLPC XO.

The crate is intended to provide a similar set of facilities as uefi-rs, that is, an abstraction over the entry point and the interfaces. I started the ieee1275-rs crate specifically for IBM’s POWER platforms, although if people want to provide support for SPARC, G3/4/5s and the OLPC XO I would welcome contributions.

There are several ways the firmware takes a payload to boot, in Fedora we use a PReP partition type, which is a ~4MB partition labeld with the 41h type in MBR or 9E1A2D38-C612-4316-AA26-8B49521E5A8B as the GUID in the GPT table. The ELF is written as raw data in the partition.

Another alternative is a so called CHRP script in “ppc/bootinfo.txt”, this script can load an ELF located in the same filesystem, this is what the bootable CD/DVD installer uses. I have yet to test whether this is something that can be used across Open Firmware implementations.

To avoid compatibility issues, the ELF payload has to be compiled as a 32bit big-endian binary as the firmware interface would often assume that endianness and address size.

The entry point

As I entered this problem I had some experience writing UEFI binaries, the entry point in UEFI looks like this:

#![no_main] #![no_std] use uefi::prelude::*; #[entry] fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status { uefi::helpers::init(&mut system_table).unwrap(); system_table.boot_services().stall(10_000_000); Status::SUCCESS }

Basically you get a pointer to a table of functions, and that’s how you ask the firmware to perform system functions for you. I thought that maybe Open Firmware did something similar, so I had a look at how GRUB does this and it used a ppc assembler snippet that jumps to grub_ieee1275_entry_fn(), yaboot does a similar thing. I was already grumbling of having to look into how to embed an asm binary to my Rust project. But turns out this snippet conforms to the PPC function calling convention, and since those snippets mostly take care of zeroing the BSS segment but turns out the ELF Rust outputs does not generate one (although I am not sure this means there isn’t a runtime one, I need to investigate this further), I decided to just create a small ppc32be ELF binary with the start function into the top of the .text section at address 0x10000.

I have created a repository with the most basic setup that you can run. With some cargo configuration to get the right linking options, and a script to create the disk image with the ELF payload on the PReP partition and run qemu, we can get this source code being run by Open Firmware:

#![no_std] #![no_main] use core::{panic::PanicInfo, ffi::c_void}; #[panic_handler] fn _handler (_info: &PanicInfo) -> ! { loop {} } #[no_mangle] #[link_section = ".text"] extern "C" fn _start(_r3: usize, _r4: usize, _entry: extern "C" fn(*mut c_void) -> usize) -> isize { loop {} }

Provided we have already created the disk image (check the run_qemu.sh script for more details), we can run our code by executing the following commands:

$ cargo +nightly build --release --target powerpc-unknown-linux-gnu $ dd if=target/powerpc-unknown-linux-gnu/release/openfirmware-basic-entry of=disk.img bs=512 seek=2048 conv=notrunc $ qemu-system-ppc64 -M pseries -m 512 --drive file=disk.img [...] Welcome to Open Firmware Copyright (c) 2004, 2017 IBM Corporation All rights reserved. This program and the accompanying materials are made available under the terms of the BSD License available at http://www.opensource.org/licenses/bsd-license.php Trying to load: from: /vdevice/v-scsi@71000003/disk@8000000000000000 ... Successfully loaded

Ta da! The wonders of getting your firmware to run an infinite loop. Here’s where the fun begins.

Doing something actually useful

Now, to complete the hello world, we need to do something useful. Remeber our _entry argument in the _start() function? That’s our gateway to the firmware functionality. Let’s look at how the IEEE1275 spec tells us how we can work with it.

This function is a universal entry point that takes a structure as an argument that tells the firmware what to run, depending on the function it expects some extra arguments attached. Let’s look at how we can at least print “Hello World!” on the firmware console.

The basic structure looks like this:

#[repr(C)] pub struct Args { pub service: *const u8, // null terminated ascii string representing the name of the service call pub nargs: usize, // number of arguments pub nret: usize, // number of return values }

This is just the header of every possible call, nargs and nret determine the size of the memory of the entire argument payload. Let’s look at an an example to just exit the program:

#[no_mangle] #[link_section = ".text"] extern "C" fn _start(_r3: usize, _r4: usize, entry: extern "C" fn(*mut Args) -> usize) -> isize { let mut args = Args { service: "exit\0".as_ptr(), nargs: 0, nret: 0 }; entry (&mut args as *mut Args); 0 // The program will exit in the line before, we return 0 to satisfy the compiler }

When we run it in qemu we get the following output:

Trying to load: from: /vdevice/v-scsi@71000003/disk@8000000000000000 ... Successfully loaded W3411: Client application returned.

Aha! We successfully called firmware code!

To be continued…

To summarize, we’ve learned that we don’t really need assembly code to produce an entry point to our OF bootloader (tho we need to zero our bss segment if we have one), we’ve learned how to build a valid OF ELF for the PPC architecture and how to call a basic firmware service.

In a follow up post I intend to show a hello world text output and how the ieee1275 crate helps to abstract away most of the grunt to access common firmware services. Stay tuned!

Alberto Ruiz: Booting with Rust: Chapter 1

Enj, 25/07/2024 - 4:10md

I have been doing random coding experiments with my spare time that I never got to publicize much outside of my inner circles. I thought I would undust my blog a bit to talk about what I did in case it is useful for others.

For some background, I used to manage the bootloader team at Red Hat a few years ago alongside Peter Jones and Javier Martinez. I learned a great deal from them and I fell in love with this particular problem space and I have come to enjoy tinkering with experiments in this space.

There many open challenges in this space that we could use to have a more robust bootpath across Linux distros, from boot attestation for initramfs and cmdline, A/B rollbacks, TPM LUKS decryption (ala BitLocker)…

One that particularly interests me is unifying the firmware-kernel boot interface across implementations in the hypothetical absence of GRUB.

Context: the issue with GRUB

The priority of the team was to support RHEL boot path on all the architectures we supported. Namely x86_64 (legacy BIOS & UEFI), aarch64 (UEFI), s390x and ppc64le (Open Power and PowerVM).

These are extremely heterogeneous firmware interfaces, some are on their way to extinction (legacy PC BIOS) and some will remain weird for a while.

GRUB, (GRand Unified Bootloader) as it names stands, intends to be a unified bootloader for all platforms. GRUB has to support a supersetq of firmware interfaces, some of those, like legacy BIOS do not support much other than some rudimentary support disk or network access and basic graphics handling.

To get to load a kernel and its initramfs, this means that GRUB has to implement basic drivers for storage, networking, TCP/IP, filesystems, volume management… every time there is a new device storage technology, we need to implement a driver twice, once in the kernel and once in GRUB itself. GRUB is, for all intent and purposes, an entire operating system that has to be maintained.

The maintenance burden is actually quite big, and recently it has been a target for the InfoSec community after the Boot Hole vulnerability. GRUB is implemented in C and it is an extremely complex code base and not as well staffed as it should. It implements its own scripting language (parser et al) and it is clear there are quite a few CVEs lurking in there.

So, we are basically maintaining code we already have to write, test and maintain in the Linux kernel in a different OS whose whole purposes (in the context of RHEL, CentOS and Fedora) its main job is to boot a Linux kernel.

This realization led to the initiative that these days are taking shape in the discussions around nmbl (no more boot loader). You can read more about that in that blog post, I am not actively participating in that effort but I encourage you to read about it. I do want to focus on something else and very specific, which is what you do before you load the nmble kernel.

Booting from disk

I want to focus on the code that goes from the firmware interface to loading the kernel (nmbl or otherwise) from disk. We want some sort of A/B boot protocol that is somewhat normalized across the platforms we support, we need to pick the kernel from the disk.

The systemd community has led some of the boot modernization initiatives, vocally supporting the adoption of UKI and signed pre-built initarmfs images, developing the Boot Loader Spec, and other efforts.

At some point I heard Lennart making the point that we should standardize on using the EFI System Partition as /boot to place the kernel as most firmware implementations know how to talk to a FAT partition.

This proposal caught my attention and I have been pondering if we could have a relatively small codebase written in a safe language (you know which) that could support a well define protocol for A/B booting a kernel in Legacy BIOS, S390 and OpenFirmware (UEFI and Open Power already support BLS snippets so we are covered there).

My modest inroad into testing this hypothesis so far has been the development of ieee1275-rs, a Rust module to write programs for the Open Firmware interface, so far I have not been able to load a kernel by myself but I still think the lessons learned and some of the code could be useful to others. Please note this is a personal experiment and nothing Red Hat is officially working on.

I will be writing more about the technical details of this crate in a follow up blog post where I get into some of the details of writing Rust code for a firmware interface, this post is long enough already. Stay tuned.

Pedro Sader Azevedo: Accessibility Hackathon

Mar, 23/07/2024 - 4:00md

When you stop and think about it, user interfaces are almost entirely designed around sight: they display graphical elements that are mostly interacted with by pointing and clicking (or touching). However, as we know, not everyone has “perfect” vision: some are color blind, some are short sighted, some are long sighted, etc. In many cases, these people can still interact with the same user interfaces as everyone else, but those with more severe visual impairments need a different method to use their computers.

That’s when the Screen Reader comes in! The Screen Reader is a software that adapts computers to the needs of users with low vision or blindness, by reading descriptions of user interfaces out loud and facilitating keyboard navigation.

Today, we will explore the web with Orca, the Screen Reader of the Linux Desktop! After that, we will contribute towards improving the experience of Orca users.

Mind you that Screen Readers have tons of advanced features to empower users with as much efficiency as possible. Because of that, it can be challenging to use this kind of software if you are not used to it. I invite you to embrace this challenge as an opportunity to experience the desktop from a different perspective, and to appreciate the way other people user their computers.

Without further ado, let’s get going!

Part I - Exploring the Screen Reader Enabling and Disabling Orca

You can enable and disable Orca by pressing Super + Alt + s. This can also be configured via GNOME Settings, under “Accessibility” > “Seeing” > “Screen Reader”.

Turn up and the volume and make sure you hear a robotic voice saying “Screen Reader on” and “Screen Reader off”. Then, open the Firefox web browser and check if Orca describes the current open tab. If it is quiet, try closing and re-opening Firefox again or disabling and re-enabling Orca.

Controlling Orca

Orca is controlled entirely from the keyboard, having dozens of shortcuts. Besides, these keyboard shortcuts are slightly different if you have a Number Pad (NumPad) or not. I have laid out the most important ones below, but an exhaustive list can be found in the quite excellent Orca documentation.

Orca Modifier Key Without a NumPad (Laptop) With a NumPad (Desktop) Orca Modifier Caps Lock NumPad Ins Important shortcuts Action Without a NumPad With a NumPad Toggle screen reader Super + Alt + s Super + Alt + s Interrupt screen reading Orca Modifier (press) Orca Modifier (press) Toggle caret mode in Firefox F7 F7 Where am I NumPad Enter Orca Modifier + Enter Display page structure Alt + Shift + h Alt + Shift + h Display page buttons Alt + Shift + b Alt + Shift + b Read current line NumPad 8 Orca Modifier + i Read current word NumPad 5 Orca Modifier + k Read onward NumPad + Orca Modifier + ; Next link k k Previous link Shift + k Shift + k Next paragraph p p Previous paragraph Shift + p Shift + p Next button p p Previous paragraph Shift + p Shift + p Activity: Exploring the web with Orca

Open the Firefox web browser and head to https://flathub.org. Find an app that looks interesting to you and explore its page using Orca. Try to navigate the entire page!

Feel free to use the questions below as a guide to your exploration:

  1. Can you read the app description? Try to do it twice.
  2. Can you click the “Install” button? What happens when you do?
  3. Can you figure out if the app is verified or not? How so?
  4. Can you guess what the screenshots of the app are showing?
  5. Can you find the link to the source code of the app?
Part II - Captioning Screenshots in Flathub Flatpak and Flathub

Flatpak is a modern packaging technology, which aims to work on all Linux distributions. In turn, Flathub is an app store for software that was packaged using Flatpak. Flathub has been embraced as the main channel for publishing applications by many projects, most notably GNOME!

App listings

Each app that is published on Flathub has a page for itself, which is called “app listing”. You will find lots of important information about an app on its listing, such as:

  • Name
  • Description
  • Author
  • License
  • Permissions
  • Screenshots

All this information is sourced from a special file called “MetaInfo File”, that is typically hosted on the app’s repository. Its filename usually ends with .metainfo.xml.in.in. You can click here to see an example of a MetaInfo File. You can read more about this file format on Flathub’s MetaInfo Guidelines.

Screenshot captions

To promote high-quality listings, Flathub publishes its own Quality Guidelines.. These guidelines encourage maintainer’s to add captions to their images, which, as we learned in the first activity, helps people who use Screen Readers understand the content of the screenshots of the app. To quote the Quality Guidelines:

Every screenshot should have a caption briefly describing it. Captions should only be one sentence and not end with a full stop. Don’t start them with a number.

To be more precise, good captions should clearly convey the functionality demonstrated in the screenshot, as well as give a general idea of the user interface on display. I have cataloged dozens of Flathub listings on this Google Sheet:

GUADEC 2024 - Accessibility Hackathon

There you find listings with Caption status set “Exemplary”, which are great models of how captions should be written.

Activity: Contributing with captions

Now, we will improve the accessibility of the Linux Desktop (albeit slightly), by contributing to Flathub with screenshot captioning. To do that, follow the instructions laid out below:

  1. Open the Google Sheet on this link
  2. Choose an app with Caption status set “Absent”
  3. Assign “In-progress” to its Caption status
  4. Put your name(s) on its Group column
  5. Head to the Flathub listing link of the app
  6. Find the repository of the app (usually under “Browser the source code” on “Links”)

  7. Log in or create an account on the platform that hosts the repository of the app (GitHub, GitLab, etc)
  8. Go back to the repository of the app, and find its MetaInfo File. It is typically placed in a data/ directory, at the root of the repository.
  9. On the MetaInfo File, look for the screenshot tags and find the files referenced in it
  10. Inside each screenshot element, there is an image element. For each of those, create a new line with caption tags. The caption goes in between them, like so:
<screenshot> <image>https://raw.githubusercontent.com/SeaDve/Kooha/main/data/screenshots/screenshot2.png</image> + <caption>In-progress recording duration and button to stop recording</caption> </screenshot>
  1. When you are done writing your captions, proof read them and run them through a spellchecker. I haven’t found any great ones online, but Language Tool’s is passable.
  2. Commit your changes, following the commit message conventions of the project you are contributing to. If this convention is not documented anywhere, try to infer it looking at the commit history.
  3. Open a Pull Request (PR) / Merge Request (MR) with your contribution, explaining what you did and why it is important. You can use my explanation as a model.
  4. Put a link to your PR/MR on the sheet.
  5. Wait for the maintainer’s feedback
Part III: Farewell

Thank you for attending this workshop. I hope you had a good time!

Until the next one!

Michael Hill: Renaming multiple files

Hën, 22/07/2024 - 6:42md

After World War II, Jack Kirby and his partner Joe Simon began their first foray into the genre of crime comics. (Kirby would return to the topic briefly in 1954 and 1971.) Beginning in 1947 and tailing into 1951, the stories appeared largely in Headline Comics and Justice Traps the Guilty for Crestwood’s Prize Publications. In 2011, Titan Books published a selection of these stories in hardcover, but sixty percent of the stories from this time period aren’t included in the book, and at least 20 stories have never been reprinted. Unlike Simon & Kirby’s much more prolific romance offerings, all of the comics in question are in the public domain and available on Digital Comic Museum and Comic Book Plus sites, thanks to multiple volunteers. I set about creating my own collection of scanned pages.

When the downloaded .cbz files are extracted into a folder, the resulting image files have names like scan00.jpg, scan01.jpg, etc. In GNOME Files, selecting all the files for a given issue and pressing F2 brings up the batch rename dialogue.

Selecting the Find and replace text option, I replace “scan” with the book title and issue number, with “p” as a separator for the page number.

When all the stories have been added, the pages will be sorted by title and issue number. To enable sorting chronologically, a four- or six-digit prefix can be used to specify the cover date, in this case “4706” for June 1947. To add this I press F2 on the same selected files and use the Rename using a template option.

Using the Jack Kirby Checklist as a guideline, and discarding (very few) stories for insufficient Kirby content, my project yielded a folder containing 633 pages including covers.

Jack Kirby (1917-1994) was a pioneer in American comic books. He grew up on the Lower East Side of New York City (where he encountered real and aspiring gangsters first hand) and fought in northeastern France in 1944 as an infantryman in Patton’s Third Army. As a partner in Simon and Kirby and the manager of the S&K studio, Kirby defined the word cartoonist—he generally wrote, penciled, inked, and occasionally coloured his own stories. Jack Kirby photo property of the Kirby Estate. Used with permission.