<?xml version="1.0" encoding="utf8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
	<title>tech</title>
	<description><![CDATA[This is a technical phlog.  The main topic is exploration and fun with
computers, networks, and unix operating systems.
]]></description>
	<link>gopher://example.conf:70/1/tech/</link>
	<item>
		<title>openSUSE on Acer Aspire One D270</title>
		<link>gopher://example.conf:70/0/tech/2024-07-11.txt</link>
		<description><![CDATA[A few days ago I've inherited a really cute laptop.

As by title, it is an Acer Aspire One D270.  It turns out there's
a wikipedia page about Acer Aspire One, and the D270 model
somehow deserved a dedicated section:
https://en.wikipedia.org/wiki/Acer_Aspire_One#Acer_Aspire_One_D270

The display of this unit was unfortunately damaged, but the
laptop was otherwise in working conditions, and I could see that
the operating system was booting regularly!

I wasn't sure whether it was worth the effort, but I decided to
tempt the fates and fix the display.  The operation succeded,
although it was a little expensive to buy a replacement.

Once the new display was mounted I could see Windows 7 Starter
reaching the login screen, where I was prompted to enter the
password for the user. I guessed it correctly as the name of the
previous owner.  Naive.  By my code of honor respected their
privacy by not looking at any of the stored data.

It should come with no surprise that there wasn't much to do for
the discontinued operating system.  Screw that, I was planning to
install Linux anyway, so I figured I shold probably try Puppy
Linux, or some other distro targeting old hardware.

With my surprise, even if the operating system managed to boot,
the computer ended up frozen as soon as the graphical server was
started.  I tried all of the available boot options, but nothing
seemed to work.  Then I decided to try with another distro, but I
got the same result.

It took a while to figure out that the `quiet` option passed by
many distros as boot parameter was responsible for this odd
behaviour.  Even so, running a lightweight desktop environment
such as XFCE4 turned out to be too much for this laptop.  The
installation procedure just froze before any installation could
be done.

Eventually I decided to give Debian a shot, since it comes with a
textual installer.  It took ages, but Debian + XFCE4 eventually
popped up, unbearably slow, but working.

After a few days of torturing myself with a very slow system
(as I didn't have a much faster workstation at my disposal)
I challenged myself to attempt the installation of openSUSE.

Why openSUSE? - you may ask.  Well, obviously I could have fixed
the perfectly working Debian by dropping XFCE4 in favour of any
of the many window managers available.  But I grew fond of
openSUSE lately, so why not?  I just decided to try, just for
fun, and because I can.

The challenge comes from the fact that openSUSE is not known to
be the most lightweight out there.  I'm quite sure there is some
minimal net install available for download, but I decided to just
use the live installed on my USB drive.

I edited the kernel command line at the boot loader, removing the
problematic `quiet` option, and adding the
`systemd.unit=multi-user.target` parameter.
The latter corresponds to "ye olde" runlevel 3 (multi-user mode
with networking, and text-only login on TTYs).

In openSUSE, the installation is started by launching a shell
script that can be found under `/sbin`.  Now I don't recall by
heart the name of it, but there are just a few commands whose
name ends with the `.sh` suffix, and that's one of them.

The installation took some time, but it ended smoothly.
By chosing the "Generic Desktop" system role, I ended up with a very
snappy system, even on such a old piece of hardware!

The system boots in a reasonable time to a text prompt.
I can optionally start a graphical session based on IceWM by
typing `startx`, exactly as it was on Slackware, when I was a
teenager.

The result? A cute little laptop, running a cute little distro.
It is unfortunately not so good at running the huge and bloated
browser that you need to surf our huge and bloated web, but
it is good enough for many other things. :)
]]></description>
	</item>
	<item>
		<title>Shellcode on a setuid program (2/?)</title>
		<link>gopher://example.conf:70/0/tech/2024-05-02.txt</link>
		<description><![CDATA[Resuming learning process of previous episode.

A fellow hacker suggested that dash also supports 'privmode', a
feature that resets euid if different from uid, disabled
with `-p`.
https://sources.debian.org/patches/dash/0.5.12-2/9002-Add-privmode-Part-2.diff/

Good to know...
Still this is not the problem, running id(1) via
execve("/bin/id") does not list the user who owns the setuid
binary.  And there's no shell interpreter invoked here.
]]></description>
	</item>
	<item>
		<title>Shellcode on a setuid program (1/?)</title>
		<link>gopher://example.conf:70/0/tech/2024-04-29.txt</link>
		<description><![CDATA[Despite the severe lack of free time, I'm currently sharpening my
security skills by doing CTFs.

My focus is on details and on building solid understanding on how
things work at low level, which is an elegant way of justifying
the fact that it takes forever for me to advance a single level.

While doing the current exercise, I've battled against a number
of things [and I regret taking notes in such a poor way].

We are talking about setuid binaries that should be convinced to
steal the flag for us.  Injecting a shellcode in this one is
trivial, as it is one of the first exercises.  My focus on the
exploit, which is where I'm less competent.

Over (way too much) time, I managed to put together a dumb
shellcode, which is just running
execve("/bin/sh", ["/bin/sh", "/bin/sh", NULL]).

I can see the shell process is running, since the prompt is
printed, but as it turns out the shell does not have the
permissions that I would expect to be granted by setuid.
Why so?

- As I learned, bash will drop privileges in case of unequal euid
  and reuid[1].
  This is a clever idea from the multi-layer security
  perspective, and overall good to know.  But the target system
  runs dash, not bash!

- I encoded a execve("/bin/id", ["/bin/id", NULL]) instead,
  learning that not even id(1) will show the correct permissions.
  This is somewhat surprising: I wrote a quick program that does
  the same, gave it setuid and a different user, and *on my
  system* it behave as I would have expected!

- Next up, I'll try capturing the flag directly, without relying
  on an exec.  I think `ragg2` will be useful for this to happen
  without spending all this time.


[1] https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html#Invoked-with-unequal-effective-and-real-UID_002fGIDs
]]></description>
	</item>
	<item>
		<title>More radare 2 (6/?): functions call graph</title>
		<link>gopher://example.conf:70/0/tech/2024-02-14.txt</link>
		<description><![CDATA[I'm investigating on a CVE concerning a well known library that
is part of our dependency tree at $dayjob.

Anything calling the vulnerable function is to be considered
vulnerable, so I wanted to obtain a call graph of the function.
An IDE would probably be able to figure that out for me, but I
don't use one.  On the other hand I'm learning Radare2 these
days, so why not using it?

Visualize global call graph: agC
    ag supports a number of graph visualization options.
    graphviz dot visualized from within r2:
        [...]> agCd | xdot -
    same but from shell:
        $ r2 -Aqc agCd ./package/usr/lib/lib....so | xdot -

Visualize xref graph: agx @ addr
    The displayed xrefs are addresses because r2 will not list
    the name of the calling function, but the address of the
    calling site within functions.
    This is not very useful for our needs, so the global call
    graph mentioned above is more practical.

While figuring out the call graph from the source code might be
more natural, the binary analysis approach has the advantage of
taking in account the compile-time configuration.
This is effective In many software packages such as Busybox,
U-Boot, Linux (kernel) and mbedTLS many features can be disabled
in the build system.
]]></description>
	</item>
	<item>
		<title>More radare 2 (5/?): environment variables etc.</title>
		<link>gopher://example.conf:70/0/tech/2024-02-13.txt</link>
		<description><![CDATA[I'm still focusing on the narnia
(https://overthewire.org/wargames/narnia/) capture the flag,
which is trivial in itself, but I'm trying to beat it completely
within R2, with the goal of learning the tool.

Radare2 is rich of features, but also baroque and inconsistently
documented.  How do I set environment variables?  Rarun is the
answer, but the documentation glosses over how that is
integrated.

Search on the web.
Find out about radare2-explorations (a complementary book)
https://monosource.gitbooks.io/radare2-explorations/content/intro/debugging.html

In a nutshell:

 1. Run `rarun2 -t` in another tty and yank the path of the
    printed character device (e.g. /dev/pts/8)

 2. Execute r2 like this:

    $ r2 -r rarun.rr2 -d program

Example with narnia1:

    $ cat rarun.rr2
    stdio=/dev/pts/8
    setenv=EGG=exploit_here

    $ r2 -r rarun.rr2 -d ./narnia1

Well, the software is powerful and intriguing, but I'm a little
frustrated by the (well known) steep learning curve, IMO mostly
due to old/inconsistent docs and opcode-like commands. For a
person like myself, who has so little free time, this is a big
obstacle.  I'm grateful nonetheless.

--
mov esi, str._bin_sh
mov edi, str._bin_sh
mov eax, 0
call sym.imp.execl
]]></description>
	</item>
	<item>
		<title>More radare 2 (4/?): filter and search</title>
		<link>gopher://example.conf:70/0/tech/2024-02-07.txt</link>
		<description><![CDATA[## Output filtering: see ~?

~ follows a command, to massage the output of it.
let `ia` be our command)
Notable variants:
 ~..         pager
 ~{path}     json
Examples:
 izz~..
 izj~{[0].vaddr}


## Searching in binary: see /?

Notable variants:
 /c    search for crypto material
Should investigate on what is available

Would it be possible to find traces of a statically compiled library (possibly
even multiple copies of it) within an executable?
]]></description>
	</item>
	<item>
		<title>More radare2 (3/?): binary editing / persisting / debugging</title>
		<link>gopher://example.conf:70/0/tech/2024-02-04.txt</link>
		<description><![CDATA[Invoke r2 with -w flag -> Write mode.

In visual mode ('V') the visual assembler 'A' is available, and
allows to enter assembly directly in place of the current seek.
=> patch binary.

Visual mode supports a number of shorcuts (listed in the book,
but also as inline help).  The `;` shortcut, allows to add
comments to the assembly.
Exercise: how to do so in normal mode?


## Flags

It is useful to place flags around, e.g when an interesting
offset is found.

    f myflag = $$    # Where $$ is the 'current seek' variable.


## Persist

I was wondering how to persist metadata.
As it turns out, radare2 can save projects and version them via
git.  Try `P?` and read up :)


## Debug

Visual debugging: `Vpp` (or `V` followed by hitting `p` twice)
Top: stack
Middle: registers
Bottom: instructions

db          List breakpoints
db main     Add breakpoint to main.
dc          Continue to breakpoint.
dsr         Step till end of frame (that is, till return)

F2 | B      toggle breakpoint   (Same as `db $$`)
F4          Run to cursor
F7 | s      Step
F8 | S      Step over
F9          Continue

What is visual diff?
]]></description>
	</item>
	<item>
		<title>Signed overflow / unsigned wrap-around</title>
		<link>gopher://example.conf:70/0/tech/2024-02-03.txt</link>
		<description><![CDATA[I've recently read this:
https://lwn.net/ml/linux-kernel/20240122235208.work.748-kees@kernel.org/

Trying to experiment a bit with what I learned:

    $ cat wrapme.c
    #include <stdint.h>
    #include <err.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <limits.h>

    int main(int argc, char **argv)
    {
        int val, ival;

        if (argc < 2)
            errx(1, "Usage: %s VALUE", argv[0]);

        val = INT_MAX;
        ival = atoi(argv[1]); // feeling lazy today.

        printf("will it overflow?\n");
        if (val + ival < val)
            printf("It will overflow\n");
        else
            printf("It won't overflow\n");

        val += ival;
        printf("%d\n", val);
        return 0;
    }

Compiled with different options...

    $ make
    gcc -o ftrapv -ftrapv wrapme.c
    gcc -o fwrapv -fwrapv wrapme.c
    gcc -o default wrapme.c

How will it behave upon signed integer overflow?

    $ ./fwrapv 0
    will it overflow?
    It won't overflow
    2147483647

    $ ./fwrapv 1
    will it overflow?
    It will overflow
    -2147483648

    $ ./ftrapv 0
    will it overflow?
    It won't overflow
    2147483647

    $ ./ftrapv 1
    will it overflow?
    Aborted (core dumped)

    $ ./default 0
    will it overflow?
    It won't overflow
    2147483647

    $ ./default 1
    will it overflow?
    It won't overflow
    -2147483648
]]></description>
	</item>
	<item>
		<title>More radare2 (2/?)</title>
		<link>gopher://example.conf:70/0/tech/2024-01-27.txt</link>
		<description><![CDATA[== xrefs ==

The dayjob monolith is using all RAM in our embedded platform.  A colleague is
trying to mitigate the problem, and he asked me if I knew a way to check the
amount of space used by strings.  Using strings(1) is of course the first thing
to do, but while doing so I've also found build paths leaked in the executable.
Classic [ab]use of __FILE__ and similar macros.

Where to find the culprit code?  radare2 has a way to find references to
simbols (in jargon we speak about "xrefs").
The command is `axt`, described as "find data/code references to this address".
In order to obtain results from `axt` enhanced binary analysis commands such as
`aa` must be executed first.

Example on narnia1 (https://overthewire.org/wargames/narnia/):

    [0x0040106e]> cat ./narnia1.c
    /*
       This program is free software; you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published by
       the Free Software Foundation; either version 2 of the License, or
       (at your option) any later version.

       This program is distributed in the hope that it will be useful,
       but WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       GNU General Public License for more details.

       You should have received a copy of the GNU General Public License
       along with this program; if not, write to the Free Software
       Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       */
    #include <stdio.h>

    int main(){
        int (*ret)();

        if(getenv("EGG")==NULL){
            printf("Give me something to execute at the env-variable EGG\n");
            exit(1);
        }

        printf("Trying to execute EGG!\n");
        ret = getenv("EGG");
        ret();

        return 0;
    }
    [0x0040106e]> fs strings
    [0x0040106e]> f
    0x00402010 53 str.Give_me_something_to_execute_at_the_env_variable_EGG
    0x00402045 23 str.Trying_to_execute_EGG_
    [0x0040106e]> aa
    INFO: Analyze all flags starting with sym. and entry0 (aa)
    INFO: Analyze all functions arguments/locals (afva@@@F)
    [0x0040106e]> axt str.Give_me_something_to_execute_at_the_env_variable_EGG
    main 0x401181 [DATA:r--] mov edi, str.Give_me_something_to_execute_at_the_env_variable_EGG


== Configuration is useful

Added ~/.radare2rc in my rcm(1).

I use light terminals at work, and dark terminals on my own machines
(this follows my life patterns: working by day, hacking at night).

    # The ogray theme works on both light and dark terminals.
    eco ogray


== Debugging session

Let's keep working on narnia1, however trivial, there's probably something to
learn from it about radare2.

First off, useful debugging commands:

  dc - continue execution of all children
 ood - reopen in debug mode

The exercise requires me to pass around an environment variable named EGG.
How do I in radare2? That's how I found out about rarun2.

My free time is so limited :(
Session is over.  Little learned is better than nothing.
]]></description>
	</item>
	<item>
		<title>More radare2 (1/?)</title>
		<link>gopher://example.conf:70/0/tech/2024-01-01.txt</link>
		<description><![CDATA[Last day of vacation, but being home with small kids completely flips
the perspective, which means that tomorrow, first day of work, will be
the actual first day of vacation...

Once everyone is in bed, I can finally indulge in learning some secret art.
Lately this means Radare2: a baroque binary analysis tool.
Let's list some commands I've been playing with:

    iI - Binary info
    af - Analyze functions
    px - Print hexadecimal

> Flags:_
Basically they are pointers: the value is usually an address in memory,
and the size property defines the size of the pointed object.  The `af`
command populates the flag space named "functions" with flags having
names such as `sym.main`.

    fs - list available flag spaces
    fs SPACENAME - enable filter on listed flags, only list from the flag space
                   named SPACENAME
    f FLAGNAME 0x10 0x23040 - Assign a flag having name FLAGNAME, size 0x10 and
                              offset 0x23040.
    f-- - Erase all flags.

> Example:_
af                  - analyze functions
fs functions        - filter flag space of functions
f | grep main       - print all flags, but grep for main
f--                 - reset the flags, losing analyzed info.

    bf FLAGNAME - set the block size to the size value of the provided flag.
    b* - display block size.

> Example:_
bf sym.main
b*

> Corollary:_
bf sym.x            - set block size the size of function x
pd sym.x            - disassemble one block starting from the beginning of x,
                      therefore the whole x.
pdf sym.x           - Same as for previous two commands, but without changing
                      the global block size.

> Dollar-prefix_

There's a bunch of variables prefixed with '$', such as...

    $l - length of the opcode at the current seek.
    $FB - function beginning
    $FS - function size
    $$ - current seek.

    ?v - Print value.

> Example:_
s sym.main        - Seek to main()
?v $l             - Print length of the first opcode.
?v $l @ sym.x     - (not tested), temporary seek to x() and print first opcode
                    length.

> Json querying?_

I've noticed that a few commands, usually suffixed with `j`, emit output in
json format.  I suppose this is useful for front-ends.
Since I learned that the pipe symbol works as in shells, I could do the
following:

    oj | jq .

where `oj` lists open files in json format, and jq(1) is used to pretty print
the resulting json.
Nice but pointless: as it turns ut, the `~` suffix allows to modify the output,
and `{}` stands for json indentation.  (hint: try `~?`).

    oj ~{}
    oj ~{[0].writable}

> Conclusions_

I spent some time fooling around the idea of loading a file in the
addressing space of a binary, so that a program (written on purpose)
that dumps data from an arbitrary address in memory will effectively
find something there, instead of crashing and burning.

I failed, but I've learned some valuable shit.

The notes above have been jotted on paper with my Parker Jotter, and
copied in this text file.  What a pleasant night!

Time to sleep now :)
]]></description>
	</item>
	<item>
		<title>X86 / X86_64 calling conventions</title>
		<link>gopher://example.conf:70/0/tech/2023-12-28.txt</link>
		<description><![CDATA[https://en.wikipedia.org/wiki/X86_calling_conventions

Who cleans the stack from function arguments?
 - Caller cleanup: caller pushes args, jumps to callee, then restores the stack
   when over.  Notable: cdecl, de facto standard on linux (gcc)
 - Callee cleanup: the callee resets the argument adding to the stack pointer.

Conventions may differ on:
 - Order of parameters to push to stack (Left-to-Right or RtL)
 - 'thiscall': how should pass the `this` pointer (common in C++, for
   non-static methods)
 - First few parameters might be passed over registers (e.g. microsoft
   fastcall), or SIMD registers (e.g. vectorcall).

X86_64: more registers, larger.
 - Both Microsoft and Unixes: use more registers for arguments.
 - Small structs might fit registers.
]]></description>
	</item>
	<item>
		<title>Learning Radare2</title>
		<link>gopher://example.conf:70/0/tech/2023-12-27.txt</link>
		<description><![CDATA[The last few days have been hectic because family.

Even so, I managed to spend some time modifying Crossbow, my own RSS/ATOM
reader, so that it uses Mini-xml instead of libmrss/libnxml.
I think I wrote on this topic before, but the long story short is that I'm
planning since long time to ditch libmrss/libnxml in favour of Mini-xml.
I wrote a library named libeccio on the top of Mini-xml, and I'm trying to
integrate it into Crossbow.
The thing is not technically difficult, but it takes forever because family.  I
eventually managed to make it work!

While running casual quality checks on the result, I figured the compiled
binary embeds the filesystem paths where it was built.  Classic issue, usually
breaking reproducible builds, and often due to the use of the __FILE__ macro.

I noticed the problem persists even after changing the code so that __FILE__ is
not used, but I couldn't trivially figure out what kept adding it.

The right tool for the job is a disassembler with xref support.  I heard of
Ghidra before, and I managed to get my answer in a couple of clicks on a very
90's Java GUI.  In case you're curious, the problem was caused by a UTHash
macro using assert(3).

This whole story woke up my interest in binary analysis, and I even if the
answer came from Ghidra, I started to be intrigued by Radare2.  I suppose it
qualifies as the most baroque software I've ever seen, but I find it
fascinating.

I found this article very good:
https://www.megabeets.net/a-journey-into-radare-2-part-1
]]></description>
	</item>
	<item>
		<title>Reads on Security (x509 certificates)</title>
		<link>gopher://example.conf:70/0/tech/2023-12-15.txt</link>
		<description><![CDATA[RFC5280

Entities:
 Users
 Certificate authority
 Registration authority
 Repositories

Repositories meant as collections of Certificates and Certificate
Revocation Lists.

Certificate VS Public Key
The certificate binds the pub key to a subject, for a specific
time interval, and gets signed by the certificate authority.
Multiple certificates constitute the "identification path"
finalized to the validation of a public key.

Certificate Authority Certificates:

Cross-certificates:
  define the trust relation between two
  certificate authorities.

Self-issued cert:
  Issuer and signer is the same entity

Self-signed cert:
  Issuer and signer is the same entity (Self-issued)
  + The contained pubkey can verify the signature.
  ROOT CERTS are Self-signed.

Certificate Revocation List:
 On a public repo, signed by CA, contains serial numbers of the
 keys revoked by the CA.
 A recent CRL needs to be verified upon certificate validation.
 The design is somewhat flawed: in the time window between CRL
 updates, a revoked certificate is considered valid.
 Alternatives: Online Certificate Status Protocol (OCSR)

Online Certificate Status Protocol (not part of RFC):
 Not implemented everywhere (e.g. certain browsers do not)
 Possible privacy issues (online check on need implies
 disclosure).
 Check wikipedia page for details.

X509 format:
  In ASN-1 (a general purpose Type Length Value format)
    [
      {
        certificate,    -> {
        sig_algorithm,       version,
        sig_value            serial_no,
      },                     signature,
      ...                    validity,
    ]                        subject_name,
                             subject_pubkey
                           }

]]></description>
	</item>
	<item>
		<title>Using DMA under FreeBSD 14</title>
		<link>gopher://example.conf:70/0/tech/2023-12-05.txt</link>
		<description><![CDATA[FreeBSD 14 ships DMA (DragonFly Mail Agent) and uses it as a default
replacement for the venerable Sendmail.

The integration is seamless thanks to mailer.conf(5).

The FreeBSD Handbook provides a few hints on how to set it up with GMail and
FastMail.  The latter happens to be my email provider of choice.

I could easily set up a smart host on my Raspberry.
]]></description>
	</item>
	<item>
		<title>Notes on electronics (learning some basics)</title>
		<link>gopher://example.conf:70/0/tech/2023-06-04.txt</link>
		<description><![CDATA[Sparkfun.com provides some useful info for an electronic newbie such
as myself.  I've seen some of this while I was a high school student, but
electronics wasn't the main path, so I barely remember about it.

These notions are just interesting for hardware hacking, but they
might also be helpful for work!

As usual, these notes are not meant to be a summary of the pages I'm
referencing: please read the full pages! :)


https://learn.sparkfun.com/tutorials/logic-levels

 Digital ommunication translates voltages into binary values.  The
 voltage on a communication line is interpreted according to ranges:

 V_oh = Output High, min voltage expressing high
 V_ol = Output Low, max voltage expressing low
 V_ih = Input High, min voltage read as high
 V_il = Input Low, max voltage read as low
 Undefined behaviour "floating" in the "noise margin"

 The ranges could be around 5V or 3.3V.  The latter takes less energy.
 3.3V is somewhat 'backward compatible' to 5V: components are able to
 generate a signal that is recognized by a 5V component.  The opposite
 holds only if the 3.3V component is 5V tolerant.


https://learn.sparkfun.com/tutorials/serial-communication

 Saying "serial protocol" usually implies using asyncrhonous serial
 communication.

 To cope with the lack of shared clock:
 - Baud rate>  Unlikely to have it beyond 115200 bps
 - Framing>
    Data chunks have variable size, e.g. 8 bits.
    Can be 5 to 9 bits, little or big endian.
    Start bit: signals begin of tx, moving line from 1 to 0
    Stop bit: end of tx, moving line form 0 to 1.
    Parity bit: basic error checking, optional

 Common standards:
 - TTL (Transistor Transistor Logic), usualy 3.3V or 5V
   where HIGH=1, LOW=0.
 - RS-232, old style, voltage range from -13V to +13V,
   or even +/-3V or +/-25V, and flipped logic (HIGH=0, LOW=1).
   Better suited for longer range communication.


https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi

 SPI (Serial Peripheral Interface) is a synchronous serial.
 The receiver end can be as simple as a shift register.
 Sampling happens on the clock edge (either 0 to 1 or opposite).
 SPI is full duplex.  The controller side defines the clock, which
 also determines the response from the peripheral.
 Chip select: held high disconnect the peripheral from the SPI bus.


Next Up: https://learn.sparkfun.com/tutorials/i2c/
]]></description>
	</item>
	<item>
		<title>Software supply chain security with podman.</title>
		<link>gopher://example.conf:70/0/tech/2023-05-31.txt</link>
		<description><![CDATA[SYNOPSIS

sudo podman image trust set -t reject default
sudo podman image trust set --type accept docker.io
sudo podman image trust set --type signedBy -f "$pubkey" docker.io

DESCRIPTION

Since my Arch Linux workstation is currently unavailable, I'm trying to
build Archiso my work laptop, where I'm running Gentoo.  In order to get
the proper build environment, the plan is to run Arch Linux in a
container.

I decided to start with a little Dockerfile, "FROM archlinux:latest".
The invocation to docker-build(1) throws me a warning about some
deprecation, so I'm probably a bit rusty about Docker.  Instead of
learning what's wrong on Docker, why not trying to switch to Podman
instead?

Podman should be a drop in replacement, but I immediately noticed
some differences along the way.  One of them is the need of a
/etc/containers/policy.json file which is specifying what policy to
adopt for image repositories.

This is good news!  I've recently participated to a security conference,
where one of the presentation is about the security of the software
supply chain, and even if nothing I heard there enlightened me that
much, the whole experience put me in a certain mood for additional
security.

The commands in the SYNOPSIS are a short path for the configuration of
/etc/containers/policy.json.  I wish I could find the public keys for
docker.io, since there would be a way to specify the public keys in use
for the account.

This is a topic I find interesting.
Do you have opionions about it?  Feel free to send me an email.
dacav at fastmail.com.
]]></description>
	</item>
	<item>
		<title>Good use for pushd / popd / dirs</title>
		<link>gopher://example.conf:70/0/tech/2023-04-05.txt</link>
		<description><![CDATA[These days I'm often working with Yocto.  A peculiar thing about
Yocto is the ridiculous amount of directories it spawns, and high
number of places in the file-system where to modify scripts or
look at generated data.

Using 'cd' to jump from one directory to the other can be quite
slow.  A possible solution could be using environment variables,
e.g.

    path1=/path/to/place/1
    path2=/where/to/find/another/place
    ...
    cd $path1
    ...
    cd $path2

A more 'casual' approach could consist in making good use of the
pushd/popd/dirs built-ins (bash).

Example shell session:

    $ cd "$(mktemp -d)"
    $ mkdir -p ./foo/bar/baz ./lol/ ./path/to/this ./path/to/that
    $ dirs
     0  /tmp/tmp.NMiIJ8GVmY
    $ pushd ./foo/bar/baz/
    /tmp/tmp.NMiIJ8GVmY/foo/bar/baz /tmp/tmp.NMiIJ8GVmY
    $ dirs
     0  /tmp/tmp.NMiIJ8GVmY/foo/bar/baz
     1  /tmp/tmp.NMiIJ8GVmY
    $ pushd +1
    /tmp/tmp.NMiIJ8GVmY /tmp/tmp.NMiIJ8GVmY/foo/bar/baz
    $ pushd ./path/to/this/
    /tmp/tmp.NMiIJ8GVmY/path/to/this /tmp/tmp.NMiIJ8GVmY /tmp/tmp.NMiIJ8GVmY/foo/bar/baz
    $ dirs
     0  /tmp/tmp.NMiIJ8GVmY/path/to/this
     1  /tmp/tmp.NMiIJ8GVmY
     2  /tmp/tmp.NMiIJ8GVmY/foo/bar/baz
    $ pushd +1
    /tmp/tmp.NMiIJ8GVmY /tmp/tmp.NMiIJ8GVmY/foo/bar/baz /tmp/tmp.NMiIJ8GVmY/path/to/this
    $ pushd ./
    foo/  lol/  path/
    $ pushd ./path/to/that/
    /tmp/tmp.NMiIJ8GVmY/path/to/that /tmp/tmp.NMiIJ8GVmY /tmp/tmp.NMiIJ8GVmY/foo/bar/baz
    /tmp/tmp.NMiIJ8GVmY/path/to/this
    $ dirs
     0  /tmp/tmp.NMiIJ8GVmY/path/to/that
     1  /tmp/tmp.NMiIJ8GVmY
     2  /tmp/tmp.NMiIJ8GVmY/foo/bar/baz
     3  /tmp/tmp.NMiIJ8GVmY/path/to/this
]]></description>
	</item>
	<item>
		<title>Lazy loading, .plt / .got / .got.plt</title>
		<link>gopher://example.conf:70/0/tech/2023-03-25.txt</link>
		<description><![CDATA[Quick notes on the topic of lazy dynamic loading, learned from "Practical
Binary Analisys" by Denniss Andriesse (Section 2.3.4).

The dynamic linker makes process execution faster by delaying the effective
loading of library functions on their first usage.
This feature can be turned off if real-time predictability is needed.

Invoking a function such as 'puts' from the .text section implies a jump to
the corresponding stub in the .plt (Procedure Linking Table) section.
The .plt section contains read-only executable code.

The first instruction of the stub is an intdirect jump to an address specified
in a dedicated pointer that belongs to the .got.plt (Global Offset Table /
Procedure Linking Table) section.  In C pseudocode:

    void (*ptr)() = got_plt[x];
    ptr();

Initially got_plt[x] is assigned to the instruction that follows the indirect
jump, so the jump effectively results in a no-op on the first execution.
The following instructions will load the parameters for the dynamic loader,
and jump to a lookup procedure internal to the dynamic loader.

The dynamic loader will assign got_plt[x] to the correct (now resolved) address
that the code intended to jump on, before effectively jumpign to it.
Subsequent calls to the same library functions will directly jump to the
resolved library procedure, without invoking the dynamic linker.

Security implications when an exploit can write got_plt[x].

.plt -> Executable, read-only, shared among all processes using the library,
        references with indirect jump the .got.plt table of the process.
        Corollary: all processes should map the .got.plt in the same address.

.got.plt -> Data, read-write, modified by the dynamic linker.
            Contains function pointers to be updated with the resolved ones.

.got -> Data, read-write, similar to .got.plt but involved in *data* rather
        than function pointers.
]]></description>
	</item>
	<item>
		<title>Reads on Security (topic: double free)</title>
		<link>gopher://example.conf:70/0/tech/2023-03-18.txt</link>
		<description><![CDATA[I spent a fairly long period without writing on this phlog.
Besides being quite busy with work, I didn't feel very inspired
to do so.  It is time to resume this practice, as much as my
limited spare time allows me to.

A few weeks ago I wanted to update these pages, since I've been
reading up on certain security topics, of which I'd like to keep
some bookmarks.

I will keep things minimal.  As a matter of fact, the least I
type, the more time I'm left with to learn.

1.  https://github.com/stong/how-to-exploit-a-double-free
Very interesting even if I didn't try the CTF.
To understand certain things I will need more info on the system
calls.
Status: Partially read.

2. https://people.eecs.berkeley.edu/~kubitron/courses/cs194-24-S14/hand-outs/bonwick_slab.pdf
Suggested by a colleague, a very good paper.
Status: Complete.

https://hammertux.github.io/slab-allocator
Out of scope beyond a certain point.
Status: Partially read.

https://sourceware.org/glibc/wiki/MallocInternals
About malloc pools, hard to follow as it is often the case for
GNU products >:-/
Status: Partially read.
]]></description>
	</item>
	<item>
		<title>Using CMake on BSD</title>
		<link>gopher://example.conf:70/0/tech/2022-12-13.txt</link>
		<description><![CDATA[As mentioned in my previous post, I have decided to migrate Crossbow to CMake.

Crossbow is supposed to support GNU/Linux, FreeBSD and OpenBSD.  Bonus points
for more UNIX-likes.  No, I don't think I'll try to make it work on Windows,
that's not my thing.

Compiling it under GNU/Linux was trivial.  Ensuring that it works under BSD
systems is the next step, and it simply requires the modification of a
few existing scripts.  They automate the installation and the execution a
collection of black-box tests, and they must re-adapted to install a
cmake project.

I started by testing on OpenBSD.  I stumbled into a problem that seems to
match some issue I've seen before, while trying to build a different
cmake project on FreeBSD.

I'm using pkg_check_modules to find my dependencies, and while CMake claims
that the dependencies were found, it later fails at supplying the system
path extensions needed to actually compile against them.

I'm not entirely sure if this problem matches the similar one that I mention,
that is what happened on FreeBSD.  In that case the fix wasn't really a fix:
I just added the extra paths manually to the CMake target which needed it.

In this case I'm aiming at a better quality, so I'm not interested in a
it-just-works kind of hack.  On the other hand I'm clueless.  I guess
I will need to delve into this problem.

But not tonight.  Tonight I'm only good for sleeping.

It doesn't look like an insurmountable problem: I'm sure that plenty of
projects using CMake have been ported to BSD, and that's exactly where I'm
going to look as first step).  Yet, if anyone reading this has a clue, feel
free to reach me (dacav at fastmail dot com).
]]></description>
	</item>
</channel>
</rss>