Start Application Without the X Bit Set

When one plays in many environments, ocassionally you can expect issues. For me one of those issues was starting Linux application from a shared drive. For reasons I won’t get into now, except to say security-related, executable (aka X) bit was removed. Thus it wasn’t possible to start application.

But, as always in Linux, there are multiple ways to skin a cat. For me the method that did wonders was usage of ld-linux library. For example, to start a.out application, one could use the following command:

/usr/lib64/ld-linux-x86-64.so.2 ./a.out

PS: This is for applications (e.g., files with ELF header). If you want to run a script without executable bit set, just call the interpreter directly, e.g.:

bash ./a.sh

Sleep Until the Next Full Second

For a bash script of mine I had to execute a certain command every second. While this command lasted less than a second, its duration was not always the same. Sometimes it would be done in 0.1 seconds, sometime in 0.5, and rarely in more than 1 second (that’s curl download for you). This variance made using a simple sleep command a bit suboptimal.

What I needed was a command that would wait until the next full second. What I needed up with was this

SLEEP_SEC=`printf "0.%03d" $((1000 - 10#$(date +%N | head -c 3)))`
if [[ "$SLEEP_SEC" == "0.000" ]]; then SLEEP_SEC="1.000"; fi
sleep $SLEEP_SEC

The first line is just taking the current nano-second count and trimming it to the first three digits that are then subtracted from 1000 and prefixed with 0.. This essentially gives millisecond precision count until the next full second. For example, if current nanosecond counter is 389123544, this would result in 0.611. And yes, you lose a bit of precision here as number gets truncated but the result will be precise enough.

If you wonder what is 10# doing here, it’s just ensuring numbers starting with 0 are not misdetected by bash as octal numbers.

The if conditional that follows is just to ensure there is at least 1 second of sleep if the previous command took less than 1 ms. Rare occurrence but cheap enough to protect against.

Finally, we send this to the sleep command which will do its magic and allow the script to continue as the next second starts. And yes, it’s not a millisecond precise despite all this calculation as sleep is not meant to be precise to start with. However, it is consistent and it triggers within the same 2-3 milliseconds almost every time. And that was plenty precise for me.

Windows as Ansible Client

I control quite a few of computers in my network using Ansible. However, one set of clients were traditionally unreachable - Windows computers. And yes, there were ways around it but early Ansible really had trouble connecting to vanilla Windows installations without any agents involved. Well, those days are over.

Since Windows has OpenSSH built-in for a while now (as an optional component), it’s almost as easy to prepare a Windows client as it is to prepare a Linux one.

The first step is to install OpenSSH and one can do it either by manual clickety-clicking or by executing the following in administrative PowerShell prompt.

Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Start-Service sshd

Set-Service -Name sshd -StartupType 'Automatic'

New-NetFirewallRule -Name "SSH-192_168_0_0" -DisplayName "SSH (192.168.0.0/16)" -Enabled True -Profile Any -Direction inbound -Protocol TCP -LocalPort 22 -RemoteAddress 192.168.0.0/16 -Action Allow  -ErrorAction SilentlyContinue

Next comes the need to create an administrative user since Windows equivalent of root user is actually disabled on most systems. And yes, you can skip this step if you’re ok with using client user for administrative tasks. I personally like to keep it separate and naming such user root helps with setup on Ansible “server” side.

Add-Type -AssemblyName System.Web

NET user /add /y root "$([System.Web.Security.Membership]::GeneratePassword(20, 2))"

NET localgroup /add Administrators root

REG add "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\Userlist" /v root /t REG_DWORD /d 0 /f

Lastly, we need to add a public SSH key for passwordless authentication. This is as easy as writing a file.

New-Item -Path "$Env:ALLUSERSPROFILE\ssh" -Force -Name "administrators_authorized_keys" -ItemType "file" -Value "ssh-ed25519 `n"

ICACLS "$Env:ALLUSERSPROFILE\ssh\administrators_authorized_keys" /inheritance:d

ICACLS "$Env:ALLUSERSPROFILE\ssh\administrators_authorized_keys" /remove "NT AUTHORITY\Authenticated Users"

And that’s all. On Ansible side we just add cmd as ansible_shell_type and we’re good. Something like this:

ansible_connection: ssh
ansible_shell_type: cmd

Indeed, one could also use powershell instead of cmd but I found cmd working for all my scenarios while PowerShell is sometimes wonky for older Windows clients.

Regardless, you can now use Ansible to change your Winodws client configuration too.

UUID Version 7 Implementation and Conundrums

During otherwise uninteresting summer, without too much noise, we got new UUID version(s). While 6 and 8 are nice numbers, version 7 got me intrigued. It’s essentially just a combination of Unix timestamp with some random bits mixed in. Exactly what a doctor might order if you want to use such UUID as a primary key in a database whose index you don’t want to fragment to hell.

Format is easy enough as its ASCII description would suggest:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           unix_ts_ms                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          unix_ts_ms           |  ver  |       rand_a          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|var|                        rand_b                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            rand_b                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

It’s essentially 48 bits of (Unix) timestamp, followed by 74 bits of randomness, with 6 remaining bits being version and variant information. While timestamp ensures that IDs generated close in time get sorted close to each other, randomness is there to ensure uniqueness for stuff that happens at the same millisecond. And, of course, I am simplifying things a bit, especially for rand_a field but you get the gist of it.

That all behind us, let me guide you through my implementation of the same.

Generating the first 48-bits is straightforward with the only really issue being endianness. Since BinaryPrimitives doesn’t really deal with 48-bit integers, a temporary array was needed.

var msBytes = new byte[8];
BinaryPrimitives.WriteInt64BigEndian(msBytes, ms);
Buffer.BlockCopy(msBytes, 2, Bytes, 0, 6);

Generating randomness has two paths. Every time new millisecond is detected, it will generate 10 bytes of randomness. The lowest 10 bits of first 2 bytes will be used to initialize random starting value (as per Monotonic Random method in 6.2). After accounting for the 4-bit version field that shares the same space, we have 2 bits remaining. Those are simply set to 0 (as per Counter Rollover Guards in the same section). I decided not to implement “bit stealing” from rand_b field nor to implement any fancy rollover handling. If we’re still in the same millisecond, 10-bit counter is just increased and it’s lower bits are written.

if (LastMillisecond != ms) {
    LastMillisecond = ms;
    RandomNumberGenerator.Fill(Bytes.AsSpan(6));
    RandomA = (ushort)(((Bytes[6] & 0x03) << 8) | Bytes[7]);
} else {
    RandomA++;
    Bytes[7] = (byte)(RandomA & 0xFF);
    RandomNumberGenerator.Fill(Bytes.AsSpan(8));
}

Despite code looking a bit smelly when it comes to multithreading, it’s actually thread safe. Why? Well, it comes to both RandomA and LastMillisecond field having a special ThreadStatic attribute.

[ThreadStatic] private static long LastMillisecond;
[ThreadStatic] private static ushort RandomA;

This actually makes each thread have a separate copy of these variables and thus no collisions will happen. Of course, since counters are determined for each thread separately, you don’t get a sequential output between threads. Not ideal, but a conscious choice to avoid a performance hit a proper locking would introduce.

The last part is to fixup bytes in order to add version bits (always a binary 0111) and variant bits (always a binary 10).

Bytes[6] = (byte)(0x70 | ((RandomA >> 8) & 0x0F));
Bytes[8] = (byte)(0x80 | (Bytes[8] & 0x3F));

Add a couple of overrides and that’s it. You can even convert it to Guid. However…

Microsoft’s implementation of UUID know to all as System.Guid is slightly broken. Or isn’t. I guess it depends from where you look at it from. If you look at it as how RFC4122 specifies components, you can see them as data types. And that’s how the original developer thought of it. Not as a binary blob but as a structure containing (little-endian on x86) numbers even though the specification clearly says all numbers are big endian.

Had it stopped at just internal storage, it would be fine. But Microsoft went as far as to convert endianness when converting 128-bit value to the string. And that is fine if you work only with Microsoft’s implementation but it causes issues when you try to deal with almost any other variant.

This also causes one peculiar problem when it comes to converting my version 7 UUID to Microsoft’s Guid. While their binary representations are the same, converting them to string format yields a different value. You can have either binary or string compatibility between those two. But never both. In my case I decided that binary compatibility is more important since you should really be using UUID in its binary form and not space-wasting hexadecimal format.

As always, the full code is available on GitHub.

[2023-01-12: Code has been adjusted a bit in order to follow the current RFC draft. Main changes are introduction of longer monotonic counter and altenate text conversion methods (Base35 and Base58).]

Disabling Horizontal Scroll on Logitech MX Master on Ubuntu 22.04

One feature that annoys the heck out of me on my MX Master is horizontal scroll. While usefulness of the horizontal scroll itself is already debatable, its positioning on MX Master is abhorrent. Side scroll wheels are extremely easy to hit by accident and they turn as soon as you even think about them. The only saving grace is that most applications don’t support them.

Under Windows, it’s easy to disable them in Logitech Options software. But Linux has no equivalent of this (and yes, I’m discounting LogiOps here, potentially unfairly so). Fortunately, Linux does offer a fine-grained control by default.

The first step is finding mouse ID under pointer devices (ignore it under keyboard).

xinput list

To verify you have the correct mouse and if you want to check which buttons horizontal scrool wheel occupies, you can use xinput test:

xinput test <id>

For MX master (and honestly pretty much any other mouse I tried), these values were 6 and 7. Thus we can simply disable them using xinput again.

xinput set-button-map <id> 1 2 3 4 5 0 0 8 9

And that has our horizontal scroll gone for good. Interestingly, while we can still see motion values, no application seems to react to those alone.

As this change will dissapear with reboot, I personally place them in .bash_profile so they get applied each time my user logs on.


PS: I also have my thumb button reconfigured.