2025-06-26: Exam *Embedded Computing 1* ======================================= .. topic:: Put your name here **NAME:** Below you find descriptions of *"situations"*, like the code of a program that you are supposed to analyse, together with an explanation. After each such situation description you see a table of *"statements"*, where each row has four fields. * **Statement**: a statement about the situation. The statement can either be true or false. * **True**: check that field with an 'x' if you think the statement is true. * **False**: check that field with an 'x' if you think the statement is false. * **Why**: *This field is optional*. If you are unsure about your answer, write a few words explaining *why* you think your answer is correct. If your reasoning is not complete nonsense, :doc:`/me ` might diverge a little from his pure boolean "correct/incorrect" grading decision. Not applying a 'x' to any of the "True" and "False" fields in a single row will render your answer incorrect, obviously, as does checking both fields. *No computers, no cellphones, no AI glasses, no earpods, no internet!* Only pen and paper. **Grading algorithm** Inside one situation, * Each row counts as 1 * The statement's outcome is calculated as * The sum of correct rows * Minus the sum of incorrect rows Globally, * Each situation has a weight attached (situations, together with their statements, are not equal in their difficulty) * The sum of the *weighted* situation outcomes is then scaled up to 40% (the theoretical part) as per :doc:`syllabus ` .. contents:: :local: .. _exam-2026-06-26-stray-pointers: Stray Pointers -------------- .. topic:: Weight 10 Say you compile and run the program below, which is obviously buggy. Consider how large the resulting suffering can become. .. literalinclude:: exam-code/stray-pointers.cpp :language: c++ .. list-table:: :align: left :header-rows: 1 :widths: 50, 5, 5, 30 * * Statement * True * False * Why * * The incident is logged, you are logged out of your computer immediately, and you may never log in again. * . * . * * * The program is compiled and run on the Raspberry Pi. The designers of that hardware platform show some kind of humor that is prevalent among the British: the GPIO hardware inside the Pi SoC has its register map starting at address 666. Depending on the value that is written to that base address, you might end up shorting 3V3 to ground on pin 25. * . * . * * * The OS intercepts a hardware exception from the Memory Management Unit (MMU) which says, "At ``666`` there is no memory allocated for the current process". As a result the OS terminates the process. * . * . * * * A fellow process on the system might have rightfully allocated memory at position ``666``, and it is that process that falls victim to your mistake. * . * . * CPU Time -------- .. topic:: Weight 10 Compared to the program from :ref:`exam-2026-06-26-stray-pointers`, the program below is not exactly buggy in that sense, but misbehaves in a certain way. .. literalinclude:: exam-code/infinite.cpp :language: c++ .. list-table:: :align: left :header-rows: 1 :widths: 50, 5, 5, 30 * * Statement * True * False * Why * * On a single-processor system, a process running that program's code will never release the processor, and no other process will ever have a chance to run again. * . * . * * * On a single-processor system, the OS kernel will interrupt the rogue process after a short time (a so-called time-slice), put it on a queue of "runnable" (but not running) processes, and give another process from that queue a chance to run. * . * . * * * On a multi-processor (say, N) system, when you run N instances of the program, the entire system will come to a halt because each processor is saturated with one such idiot. * . * . * * * On a multi-processor system, the OS will increase the CPU frequency to satisfy the needs of its users. This can lead to not only severe damage of the CPU, but also your house may burn down. * . * . * .. _exam-2026-06-26-i2c-permissions: Permissions (``/dev/i2c-1``) ---------------------------- .. topic:: Weight 14 .. code-block:: console $ ls -l /dev/i2c-1 $ crw-rw---- 1 root i2c 254, 0 Jun 15 22:52 /dev/i2c-1 ``/dev/i2c-1`` is a character device which permits userspace programs to communicate with I2C devices that are present on the local computer. One is able to write a program that opens ``/dev/i2c-1`` just like any other, regular, file. Requests to the device are sent onto the I2C bus using the ``write()`` system call, where responses are received using ``read()``. Lets say that ... * Inside the project that builds the I2C-speaking application, there exists a strong requirement that **never, ever** a program must run as root. Rather, all programs that belong to the application must run under the credentials of the user ``application``. * Currently, the credentials of user ``application`` are .. code-block:: console $ id application uid=1001(application) gid=1001(application) groups=1001(application) For a program that will run as user ``application``, and that intends to communicate with an I2C device, consider the viability of each of the following options. .. list-table:: :align: left :header-rows: 1 :widths: 50, 5, 5, 30 * * Statement * True * False * Why * * Run the program as root. This will solve the ``/dev/i2c-1`` permission problem. * . * . * * * Btw., running a program as root can have severe consequences. If the program contains malicious (or only buggy) code, it might be able to format your disk, for example. * . * . * * * Ask the administrator of the system that will host the application to add the user ``application`` to the ``i2c`` group * . * . * * * Convince your manager to spend $$ on Anthropic Mythos 5 to find another exploitable Linux kernel bug. Embed the generated exploit into the application to impersonate user ``application`` as ``root`` on every startup of the application. * . * . * Permissions (``/etc/passwd``) ----------------------------- .. topic:: Weight 10 ``/etc/passwd`` is the user database on Linux/UNIX systems (there are other kinds of user database on Linux too, but ``/etc/passwd`` has been there since the Epoch). Lets say the relevant metadata of ``/etc/passwd`` are as follows: .. code-block:: console $ ls -l /etc/passwd -rw-r--r--. 1 root root 3401 Apr 22 12:16 /etc/passwd And the following program is compiled and run as user ``application`` (the same as in :ref:`exam-2026-06-26-i2c-permissions`) .. literalinclude:: exam-code/passwd-trunc.cpp :language: c++ .. list-table:: :align: left :header-rows: 1 :widths: 50, 5, 5, 30 * * Statement * True * False * Why * * The process will be able to open ``/etc/passwd`` for writing, but truncating the file will fail, and the exit code will silently be 0 (disregarding the truncate failure) * . * . * * * The exit code of the program is 1 * . * . * * * The exit code of the program is 0 * . * . * Polymorphic Types (Subtle) -------------------------- .. topic:: Weight 10 The following program contains a class hierarchy which exhibits a classic interface/implementation kind of design (though its functionality is rather pointless). .. literalinclude:: exam-code/polymorphic-nocompile.cpp :language: c++ Consider the truth values of each of the following statements about that program. .. list-table:: :align: left :header-rows: 1 :widths: 50, 5, 5, 30 * * Statement * True * False * Why * * The output of the program, once compiled, is .. code-block:: console $ ./program 666 * . * . * * * The program crashes because ``AnyFoo::do_something()`` is abstract * . * . * * * The program does not compile because ``AnyFoo::do_something()`` is abstract * . * . * * * Your computer will turn in to an expensive brick because ``AnyFoo::do_something()`` ends up referring to a function inside the kernel that makes the hardware watchdog bite the power management unit * . * . * Polymorphic Types (Even More Subtle) ------------------------------------ .. topic:: Weight 12 Here is a variation of the program from :ref:`exam-2026-06-26-stray-pointers` which makes use of commandline arguments and varies its execution behaviour depending on an argument that it requires. .. literalinclude:: exam-code/polymorphic.cpp :language: c++ Be ``program`` the name of the resulting executable. Consider the truth values of each of the following statements about that program. .. list-table:: :align: left :header-rows: 1 :widths: 50, 5, 5, 30 * * Answer * True * False * Why * * When called like ``./program boring``, the program's output is ``42`` * . * . * * * When called like ``./program boring``, the program's output is ``7`` * . * . * * * When called like ``./program inferior``, the program's output is ``666`` * . * . * * * When called like ``./program inferior``, the program crashes * . * . * * * When called like ``./program inferior``, the program does not compile * . * . *