Swipe right! [L]
Linkedin becomes a dating service.
You might not find a job, but maybe you can find love?
Only 25 of 16 posts are displayed. Show all entries
Linkedin becomes a dating service.
You might not find a job, but maybe you can find love?
A German hospital sent 100k+ patient records to the wrong email address (secondary source).
Apparently, they fat-fingered the email address, and now they're trying to track down the recipient.
There are no details on whether the records were at least encrypted. Healthcare providers usually have a common encrypted API for exchanging this kind of data, so sending it via email sounds like a major fuckup.
And let's go back to the "tracking down the recipient" part. Imagine someone makes a typo,
and now the police are standing at your door, demanding that you delete an email from your device.
They'll probably have to contact your email provider as well.
Not blaming the police here, the hospital is responsible for causing so much damage to so many individuals.
Tags: Emmendingen Krankenhaus Data Breach
After an update I could not attach files in Thunderbird anymore. It turned out, that I got gnomed.
After consulting the log via journalctl --user -f -u xdg-desktop-portal.service I got hit with:
/usr/lib/xdg-desktop-portal[1250]: Backend call failed: Could not activate remote peer 'org.freedesktop.impl.portal.desktop.gtk': startup job failed
Looking at the xdg portal application using systemctl --user status xdg-desktop-portal-gtk, it
told me that it's actually inactive.
It seems that it was suddenly missing env vars, which can be supplied via:
systemctl --user import-environment DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS
Put this into your .xinitrc right before you start i3 (or some other WM) so it persists between
sessions.
Tags: Arch Linux XDG X11 GNOMED
Apparently, Sony has removed over 550 movies from users' PSN accounts.
The reason is a licensing agreement with Studio Canal.
Unfortunately, this is one of the risks of streaming or cloud services. As long as something is not physically in your posession and does not function independently of external servers, you don't truly own it.
Cloud-based services are rarely about convenience for users, they're often about taking away control and your money.
Last evening Germany's national rail operator experienced an
outage regarding their GSM-R network.
Apparently this was due to a failed software update, which is expected to be fully resolved by
the next morning.
It's nice to see, that they were able to pinpoint the issue so fast and apply fixes.
Of course with the advent of LLMs the first question would be if this is a consequence of LLM generated code and LGMT'ed by a human reviewer, but I think (or I hope) that this was a good old human made mistake which we can learn from, and prevent further issues from occurring.
According to the news Elon Musk becomes a trillionaire.
This is a million: 1_000_000
This is a billion: 1_000_000_000
This is a trillion: 1_000_000_000_000
Note: short scale
Joanathan Pie shares a few words about it.
Vulnerabilities are not fun. But you can at least disclose the (already patched) vulnerability in a very fun way.
The security researcher published the vulnerability as "Bumsrakete". German readers will probably giggle - at least I did.
To summarize the technical aspect: The vulnerability is a kernel bug in FreeBSD.
Affecting versions from 13.0 to 15.0.
Any unprivileged user can write bytes into a page-cache of any file, which has read access.
It bypasses the VFS (Virtual File System) and essentially every checks to ensure security.
Now that the serios part is over, I present you a collection of money quotes:
The CVSS people, very sad people, sometimes the worst people, capped severity at 10.0. We had to invent a new scale because this bug demanded it. Tremendous demand. 13/10. Nobody knew kernel bugs could be this big. Many such cases.
The PoC dropped the second FreeBSD-SA-26:26.kTLS went live. Responsible disclosure achieved. Some people are saying the most responsible disclosure of all time.
They said it couldn't be done. They said no security team has ever shipped a patch this beautiful, this clean, this TREMENDOUS. They were wrong, like they always are. secteam@ dropped FreeBSD-SA-26:26.kTLS today and very smart people — the smartest, really — are calling it the greatest patch of our generation. Some are calling it the greatest patch of any generation. I would not say that myself. But people are saying.
And of course you have to close it with:
THANK YOU FOR YOUR ATTENTION TO THIS MATTER!
That being said, update your systems!
Back in 2024 Microsoft announced that they'll "prioritize security abolve all else".
Now it's 2026, lets look into this promise,
shall we?
Six 0-days, three under active exploitation [...]
[...] the disgruntled bug hunter with a deep understanding of Windows and an even deeper grudge against Microsoft, reached a fever pitch, with the researcher, who has thus far released six Windows zero-days [...]
To wrap this up, a security researcher worked together with the MSRC (Microsoft Security Response Center).
Allegedly, Microsoft just defines security bugs as bad documented feature
or refuses to pay for successful bug bounties.
Which causes frustration among researchers and puts customers already into danger.
The industry kinda agreed on a bug disclosure period of 90 days, if the vendor didn't managed to release a patch within 90 days, the documentation of said exploit will be published.
Usually this works well and 90 days are enough to develop a patch and coordinate between other
affected parties.
But not at Microsoft apparently. Which led the above mentioned security researcher to unleash a
series of exploits.
Note: It seems to be the case, that those specific exploits where unknown to Microsoft prior release. The details are quite fuzzy there.
But alright, now we're in a mess. Lets resolve this. Microsoft! What's your response?
Uncoordinated disclosures that put proof-of-concept code for unpatched vulnerabilities into the hands of bad actors are never justifiable and have real-world consequences.
Yes! I agree! But this only works, if you actually accept bugs as bugs, and not as bad documented features.
Our security teams across the company work tirelessly tracking threat actors who look for weaknesses just like these to attack Microsoft and our customers.
Are we now talking about criminals or security researchers? I'm confused ...
Our Digital Crimes Unit will continue bringing cases against these actors and those that enable their criminal activity – coordinating as needed with law enforcement around the world.
Now I'm lost. I thought this press release should address the situation, where Microsoft seems to work against security researchers?
Lets listen to Katie Moussouris, founder and CEO of Luta Security:
The mention of the Digital Crimes Unit in a post discussing vulnerability disclosure makes the post vaguely threatening, which seems intentional, but then they wrap up the post saying they welcome reports regardless of disclosure history [...]. Whatever the facts, it's hard to imagine why Microsoft would not try to deescalate, if for no other reason than avoiding the chilling effect on other researchers.
Let me tell you how this whole thing should work.
That's it. And if you still manage to f this up, you shouldn't be in this industry.
Adding another wisdom: Companies and unfortunately news outlets spread the narrative, that everybody is in danger, as soon someone publicly releases an exploit.
Which is not entirely true. Customers are in danger as soon a company pushes buggy software. Malicious actors try to not expose the existence of an exploit - otherwise they have to find a new one. And this is expensive!
Every published exploit gives the affected entities now a chance to act! Sure, it's now an ugly race who closes the vulnerability before some script kiddie nukes your server - this is bad. But having zero knowledge of an existing vulnerability in your system is even worse!
So please be aware if companies start again to shape a certain narrative against researchers.
If you teach students programming and you need a good metaphor, what imperative and declarative programming is, here you go:
Declarative is like pulling up to a drive-through, placing your order, and picking it up at the second window.
Imperative is when you place your order and the person behind the counter says: "Sure, but you'll have to cook it yourself."
IPv6 is now 11 years old since its ratification. Or 28 years since its first draft.
The adoption is still slow. Google made an overview
how many Google users worldwide are accessing them over IPv6, which is 50% at this time.
IPv6 is quite different from IPv4. Which made an adoption very difficult and costly. And not every company was willing to put money into it, especially when the address space issue got "solved" by CGNATs (imagine very big fat quotation marks around the word 'solved').
Now fast forward to the year 2026, a new draft got published at the IETF. It's about IPv8.
It tackles the following main problems:
And it looks like this:
IPv8: 0.0.0.0.0.0.0.0
IPv4: 0.0.0.0
You might think, didn't IPv6 solved the address space exhaustion? And you're right!
But according to the authors, IPv6 didn't solved the fragmentation of network services.
They argue, that we have a bunch of tools that aren't always designed to work together.
Quote:
DHCP, DNS, NTP, logging, monitoring, and authentication are separate products, separately licensed, separately configured, and separately maintained with no shared awareness of network state. A device connecting to a network may require manual configuration of a dozen independent services before it is operational. Security is inconsistent -- some services are authenticated, others are not. Failures require correlating data across systems that were never designed to work together.
Which sounds nice on paper, but I'm not sure how they want to achieve this through the protocol itself. They mention it again here:
IPv8 addresses this by defining a coherent management suite in which every service shares a common identity model (OAuth2 JWT), a common delivery mechanism (DHCP8), a common telemetry format (NetLog8), and a common authentication cache (OAuth8)
But this isn't helpful to me. Also, I see JWT, I see red flag. I do not understand why they need specifically JWT here and it isn't elaborated elsewhere.
Carrying on to the next topic, security.
First, every outbound connection must have a corresponding DNS8 lookup -- no DNS lookup means no XLATE8 state table entry means the connection is blocked.
Second, the destination ASN is validated against the WHOIS8 registry -- if the destination prefix is not registered as an active route by a legitimately registered ASN holder the packet is dropped.
These two steps together eliminate the primary malware command-and-control channel: connection to hardcoded IP addresses without DNS resolution.
This sounds also nice on paper. But now having an mandatory domain - controlled by some entity again - also cuts away freedom.
Maybe it's a good thing that IPv4 and v6 are "dumb" and our tools don't always share network state?
Apparently this draft is partially or fully written by an LLM. Which could explain why it felt so off.
I cannot find a primary source that confirms this, only several blogs, Reddit and Hackernews threads
came to the conclusion.
Given how weird the draft is (JWT in IP?!), it is likely to be LLM generated.
The article is from March 13, 2026 and got published by
I didn't read it. I always liked the anonymity of the artist. And I'll continue to stay uninformed on that matter.
Tags: Banksy
From Microsoft:
Satya Nadella, Chairman and CEO, shared the below communication with Microsoft employees. [...] Today, I want to talk about something critical to our company’s future: prioritizing security above all else.
In the meantime, we'll keep an eye on the CVE dataset.
Native apps are back on the menu!
A few months ago, Rudy Huyn, a Partner Architect at Microsoft working on the Store and File Explorer, officially confirmed that Microsoft plans to build 100% native apps for Windows 11.
This stems from the fact, that Microsoft used React Native in their taskbar.
Users on the social platform X have identified performance problems linked to the Windows 11 Start Menu, noting that the component utilizes React Native.
If you're running Ableton Live 11 on Linux via Wine, you may have encountered black rectangles all over the place, or even the whole screen is flickering.
The following option fixed it for Ableton and the Plugins "Saturn" and "Fabfilter". But "Serum" is still affected. Maybe Serum uses a different GUI rendering backend.
cd ~/.wine/drive_c/users/{user}/AppData/Roaming/Ableton/Live 11.3.42/Preferences/options.txt-_ForceGdiBackendI don't know if the following information is relevant for you, but this is my systems overview:
I hope it helped :)
We're answering two questions:
The language doesn't matter. I've only choosen Rust, because I'm currently on my Rust arc.
The algorithm can be implemented by recursion, or by iteration. I'm covering the iterative approach, because - for me - it's easier to reason about it.
Let's dive in
Short primer what a permutation of a set is:
Assume we have the set (1, 2, 3). The permutation of this would be all the possible positional combinations of the members.
For example:
P1 -> 1 2 3
P2 -> 1 3 2
P3 -> 3 1 2
P4 -> 3 2 1
P5 -> 2 3 1
P6 -> 2 1 3
Side note: The factorial of the size of the set represents the maximum permutation:
len(permutate(1, 2, 3)) == factorial(len((1, 2, 3)))
In SJT, integers are bound to "directions", where they can point to the left or right.
At initialization, all integers are pointing to the left, like that:
<1 <2 <3
And under certain conditions (described down below), they can reverse the direction:
3> <2 <1
Those integers are defined as "mobile integers".
A mobile integer is ...
An edge is defined as the "end" of a set:
Edge
v
| <1 <2 <3 |
^
Edge
And given this constellation:
<2 <1 3>
There are no mobile integers, since:
Exit rule: If there are no mobile integers, the algorithm is done
The following example is split into each permutation step. P<number> indicates the current permutation.
And (Step n) corresponds to the steps from the paragraph Basic Algorithm.
Init <1 <2 <3 // initialize the direction of all integers, so they're pointing to the left
P1 <1 <2 <3 // (Step 1) find the highest mobile integer, which is "3"
P2 <1 <3 <2 // (Step 2) swap positions
<1 <3 <2 // (Step 3) since there's no integer larger than (k), we skip this step
<1 <3 <2 // (Step 1) again; "3" is the largest mobile integer
P3 <3 <1 <2 // (Step 2) swap again
<3 <1 <2 // (Step 3) no greater integer than (k), we skip it again
<3 <1 <2 // (Step 1) "3" isn't mobile, since it points to an edge. So we take "2"
P4 <3 <2 <1 // (Step 2) swap "2" with "1"
3> <2 <1 // (Step 3) "3" is larger than (k), so we reverse the direction of "3"
3> <2 <1 // (Step 1) since (Rule 3) of the definition, only "3" complies with the definition
P5 <2 3> <1 // (Step 2) "3" pointed to the right, so it swaps positions with "2"
<2 3> <1 // (Step 3) there's no integer larger than (k)
<2 3> <1 // (Step 1) "3" is the largest mobile integer again.
// Since "2" points to an edge, and "1" points to an larger integer
P6 <2 <1 3> // (Step 2) swap "3" with "1"
<2 <1 3> // (Step 3) there's no larger integer than (k), so we skip again
<2 <1 3> // (Step 1) there's no mobile integer anymore, because
// "2" & "3" are pointing to an edge; "1" points to an larger number
End // And without any mobile integers, the algorithm is terminated
Credits to cut-the-knot.org which helped me a lot, to understand the algorithm.
We're walking through the full implementation step by step. You can view the Complete Implementation.
It is important to mention, that the following function is meant to generate permutations for vector indexing.
$ foo = ["A", "B", "C"]
$ apply_permutation_on_index(foo)
[["A", "B", "C"], ["A", "C", "B"], ["C", "A", "B"], ...]
Thats the reason why the function only takes one parameter, and assumes 0..n.
So adapt it to your personal needs.
1 fn permutation(n: usize) -> Vec<Vec<usize>> {
For example you want the permutations of (0, 1, 2):
With n you declare the size of the set. If you provide 3, it will generate (0, 1, 2).
Regarding the return type, it depends on your use case. So you might want a different return type for your project.
Side note: I'm sticking to the word "set" to be consistent - although the structure in Rust is a vector.
In this walkthrough, we declare that n = 3.
2 let mut perm: Vec<usize> = (0..n).collect(); // generating the "set"
3 let mut direction: Vec<i32> = vec![-1; n]; // initialize a vector with -1, which represents
// the direction of the values in `perm`
4 let mut result: Vec<Vec<usize>> = Vec::new(); // the permutated values will be stored here
5
6 let factorial = (1..=n).product(); // calculating the max possible permutation steps,
// so we can use it as an upper bound for the loop
7
8 result.push(perm.clone()); // storing the first permutation
At line 3 we created a structure, that looks like this: [-1, -1, -1].
The negative sign indicates, that the mobile integer is pointing to the left.
If there's no sign, then the mobile integer points to the right.
10 for _ in 0..factorial {
11 let mut mobile_index = None;
12
13 for i in 0..n {
14 if (direction[i] == -1 && i > 0 && perm[i] > perm[i - 1])
15 || (direction[i] == 1 && i < n - 1 && perm[i] > perm[i + 1])
16 {
17 if mobile_index.is_none() || perm[i] > perm[mobile_index.unwrap()] {
18 mobile_index = Some(i);
19 }
20 }
21 }
At line 10 we're looping 5 times: for _ in 0..6.
But why only five times? Since the maximum permutation step is 3! == 6?
Because we already saved the first permutation at line 8.
At line 11 our mobile_index represents (k), as described in the paragraph Basic Algorithm.
The inner loop at line 13 resolves into for i in 0..3, which corresponds to our "set" of 0, 1, 2
At line 14 & 15 we have a few conditions. To make this easier, we look into the first iteration,
where i = 0:
// i = 0; n = 3
if (direction[i] == -1 // IF the direction of `i` points to the left
&& i > 0 // AND `i` is greater than 0 (our leftmost edge)
&& perm[i] > perm[i - 1]) // AND the current mobile integer of our "set" is greater than the left one
|| (direction[i] == 1 // OR the direction of `i` points to the right
&& i < n - 1 // AND `i` is smaller than the maximum integer in the "set"
// Side note: Since `0..n` is non-inclusive, we have to subtract by one,
// to get the correct integer in the loop
&& perm[i] > perm[i + 1]) // AND the current mobile integer is greater than the right one
Since the condition will short-circuit to false, because 0 > 0 == false, it will skip the inner if block, and continue further.
Basically, this if block evaluates the rules from the paragraph Basic Algorithm, and searches for a mobile integer.
Let's proceed with the inner if block. Where we assume i = 1:
// i = 1
if mobile_index.is_none() // IF mobile_index contains no value
|| perm[i] > perm[mobile_index.unwrap()] { // OR the current mobile integer is
// greater than last mobile integer
mobile_index = Some(i); // Store the current mobile integer
Since mobile_index contains no value, we store 1 in it. The next iteration will be i = 2, and it will overwrite the mobile_index value.
Which now proceeds further ahead.
23 let mobile_index = match mobile_index {
24 Some(index) => index,
25 None => break,
26 };
27
28 let new_index = (mobile_index as isize + direction[mobile_index] as isize) as usize;
29 perm.swap(mobile_index, new_index);
30 direction.swap(mobile_index, new_index);
At line 23 - 26 we got the exit condition, as described in Basic algorithm.
When there's no mobile index, it breaks the outer loop and returns the result.
At line 28, the code can be broken down to: new_index = mobile_index + direction[mobile_index].
If we assume mobile_index = 2, the variable results into: new_index = 2 + -1 -> new_index = 1.
After that, in line 29 & 30, we perform the swaps:
// pre swap:
// perm = [0, 1, 2]
// direction = [-1, -1, -1]
perm.swap(2, 1);
direction.swap(2, 1);
// post swap:
// perm = [0, 2, 1]
// direction = [-1, -1, -1]
The perm and direction structures are tied together, so we have to modify both.
32 let moved_value = perm[new_index];
33
34 for i in 0..n {
35 if perm[i] > moved_value {
36 direction[i] *= -1;
37 }
38 }
39 result.push(perm.clone());
In this section, we have to evaluate, if there are any directions to reverse.
At line 32 we store the current position of the mobile integer (k). Following with a comparison,
if there's any integer higher than (k), we reverse the direction of the affected integers.
Finally, we append the current permutation to our result vector. And if the exit condition is met, if will return the final value.
This implementation is not optimized, since there are a few clone() scattered around, and might
degrade performance.
And I somehow have the gut feeling, that this can be solved without an additional direction vector.
But this may be a task for a different day.
1 fn permutation(n: usize) -> Vec<Vec<usize>> {
2 let mut perm: Vec<usize> = (0..n).collect();
3 let mut direction: Vec<i32> = vec![-1; n];
4 let mut result: Vec<Vec<usize>> = Vec::new();
5
6 let factorial = (1..=n).product();
7
8 result.push(perm.clone());
9
10 for _ in 0..factorial {
11 let mut mobile_index = None;
12
13 for i in 0..n {
14 if (direction[i] == -1 && i > 0 && perm[i] > perm[i - 1])
15 || (direction[i] == 1 && i < n - 1 && perm[i] > perm[i + 1])
16 {
17 if mobile_index.is_none() || perm[i] > perm[mobile_index.unwrap()] {
18 mobile_index = Some(i);
19 }
20 }
21 }
22
23 let mobile_index = match mobile_index {
24 Some(index) => index,
25 None => break,
26 };
27
28 let new_index = (mobile_index as isize + direction[mobile_index] as isize) as usize;
29 perm.swap(mobile_index, new_index);
30 direction.swap(mobile_index, new_index);
31
32 let moved_value = perm[new_index];
33
34 for i in 0..n {
35 if perm[i] > moved_value {
36 direction[i] *= -1;
37 }
38 }
39 result.push(perm.clone());
40 }
41 result
42 }
If you're cross compiling with Rust, you're possibly using Cross.
In some projects, you might encounter an error message regarding missing libssl.
For example:
Could not find directory of OpenSSL installation [...]
The (to me) cleanest solution is, to create a Cross.toml file in your project root dir,
and declare the libssl installation for each target.
Example:
[target.x86_64-unknown-linux-gnu]
pre-build = [
"apt update",
"apt install libssl-dev -y"
]
[target.aarch64-unknown-linux-gnu]
pre-build = [
"dpkg --add-architecture $CROSS_DEB_ARCH",
"apt-get update && apt-get --assume-yes install libssl-dev:$CROSS_DEB_ARCH"
]
I do not know where I found this solution. Somewhere deep in the web, buried between some dirty hacks. But this solved, at least, my problem.