[$] Approaches to reducing TLB pressure

Post Syndicated from corbet original https://lwn.net/Articles/1016009/

The CPU’s translation lookaside buffer (TLB) caches the results of
virtual-address translations, significantly speeding memory accesses. TLB
misses are expensive, so a lot of thought goes into using the TLB as
efficiently as possible. Reducing pressure on the TLB was the topic of Rik
van Riel’s memory-management-track session at the 2025 Linux Storage,
Filesystem, Memory-Management, and BPF Summit. Some approaches were
considered, but the session was short on firm conclusions.

Security updates for Wednesday

Post Syndicated from jzb original https://lwn.net/Articles/1016205/

Security updates have been issued by Debian (firefox-esr, jetty9, openjpeg2, and tomcat9), Fedora (dokuwiki, firefox, php-kissifrot-php-ixr, php-phpseclib3, and rust-zincati), Red Hat (kernel and pki-core), Slackware (mozilla), SUSE (apparmor, atop, docker, docker-stable, firefox, govulncheck-vulndb, libmodsecurity3, openvpn, upx, and warewulf4), and Ubuntu (inspircd, linux, linux-aws, linux-gcp, linux-gke, linux-gkeop, linux-ibm,
linux-lowlatency, linux-lowlatency-hwe-6.8, linux-oem-6.8, linux-oracle,
linux-oracle-6.8, linux-aws, linux-aws-5.4, linux-aws-fips, linux-azure-6.8, linux-hwe-6.8, linux-raspi, linux-realtime, nginx, phpseclib, and vim).

A steam locomotive from 1993 broke my yarn test

Post Syndicated from Yew Leong original https://blog.cloudflare.com/yarn-test-suffers-strange-derailment/

So the story begins with a pair programming session I had with my colleague, which I desperately needed because my node skill tree is still at level 1, and I needed to get started with React because I’ll be working on our internal backstage instance.

We worked together on a small feature, tested it locally, and it worked. Great. Now it’s time to make My Very First React Commit. So I ran the usual git add and git commit, which hooked into yarn test, to automatically run unit tests for backstage, and that’s when everything got derailed. For all the React tutorials I have followed, I have never actually run a yarn test on my machine. And the first time I tried yarn test, it hung, and after a long time, the command eventually failed:

Determining test suites to run...

  ● Test suite failed to run

thrown: [Error]

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
🌈  backstage  ⚡

I could tell it was obviously unhappy about something, and then it threw some [Error]. I have very little actual JavaScript experience, but this looks suspiciously like someone had neglected to write a proper toString() or whatever, and thus we’re stuck with the monumentally unhelpful [Error]. Searching the web yielded an entire ocean of false positives due to how vague the error message is. What a train wreck!

Fine, let’s put on our troubleshooting hats. My memory is not perfect, but thankfully shell history is. Let’s see all the (ultimately useless) things that were tried (with commentary):

2025-03-19 14:18  yarn test --help                                                                                                  
2025-03-19 14:20  yarn test --verbose                    
2025-03-19 14:21  git diff --staged                                                                                                 
2025-03-19 14:25  vim README.md                    # Did I miss some setup?
2025-03-19 14:28  i3lock -c 336699                 # "I need a drink"            
2025-03-19 14:34  yarn test --debug                # Debug, verbose, what's the diff
2025-03-19 14:35  yarn backstage-cli repo test     # Maybe if I invoke it directly ...
2025-03-19 14:36  yarn backstage-cli --version     # Nope, same as mengnan's
2025-03-19 14:36  yarn backstage-cli repo --help
2025-03-19 14:36  yarn backstage-cli repo test --since HEAD~1   # Minimal changes?
2025-03-19 14:36  yarn backstage-cli repo test --since HEAD     # Uhh idk no changes???
2025-03-19 14:38  yarn backstage-cli repo test plugins          # The first breakthrough. More on this later
2025-03-19 14:39  n all tests.\n › Press f to run only failed tests.\n › Press o to only run tests related to changed files.\n › Pres
filter by a filename regex pattern.\n › Press t to filter by a test name regex pattern.\n › Press q to quit watch mode.\n › Press Ent
rigger a test run all tests.\n › Press f to run only failed tests.\n › Press o to only run tests related to changed files.\n › Press
lter by a filename regex pattern.\n › Press t to filter by a test name regex pattern.\n › Press q to quit watch mode.\n › Press Enter
gger a test ru                                     # Got too excited and pasted rubbish
2025-03-19 14:44  ls -a | fgrep log
2025-03-19 14:44  find | fgrep log                 # Maybe it leaves a log file?
2025-03-19 14:46  yarn backstage-cli repo test --verbose --debug --no-cache plugins    # "clear cache"
2025-03-19 14:52  yarn backstage-cli repo test --no-cache --runInBand .                # No parallel
2025-03-19 15:00  yarn backstage-cli repo test --jest-help
2025-03-19 15:03  yarn backstage-cli repo test --resetMocks --resetModules plugins     # I have no idea what I'm resetting

The first real breakthrough was test plugins, which runs only tests matching “plugins”. This effectively bypassed the “determining suites to run…” logic, which was the thing that was hanging. So, I am now able to get tests to run. However, these too eventually crash with the same cryptic [Error]:

PASS   @cloudflare/backstage-components  plugins/backstage-components/src/components/Cards/TeamMembersListCard/TeamMembersListCard.test.tsx (6.787 s)
PASS   @cloudflare/backstage-components  plugins/backstage-components/src/components/Cards/ClusterDependencyCard/ClusterDependencyCard.test.tsx
PASS   @internal/plugin-software-excellence-dashboard  plugins/software-excellence-dashboard/src/components/AppDetail/AppDetail.test.tsx
PASS   @cloudflare/backstage-entities  plugins/backstage-entities/src/AccessLinkPolicy.test.ts


  ● Test suite failed to run

thrown: [Error]

Re-running it or matching different tests will give slightly different run logs, but they always end with the same error.

By now, I’ve figured out that yarn test is actually backed by Jest, a JavaScript testing framework, so my next strategy is simply trying different Jest flags to see what sticks, but invariably, none do:

2025-03-19 15:16  time yarn test --detectOpenHandles plugins
2025-03-19 15:18  time yarn test --runInBand .
2025-03-19 15:19  time yarn test --detectLeaks .
2025-03-19 15:20  yarn test --debug aetsnuheosnuhoe
2025-03-19 15:21  yarn test --debug --no-watchman nonexisis
2025-03-19 15:21  yarn test --jest-help
2025-03-19 15:22  yarn test --debug --no-watch ooooooo > ~/jest.config

A pattern finally emerges

Eventually, after re-running it so many times, I started to notice a pattern. So by default after a test run, Jest drops you into an interactive menu where you can  (Q)uit, Run (A)ll tests, etc. and I realized that Jest would eventually crash, even if it’s idling in the menu. I started timing the runs, which led me to the second breakthrough:

› Press q to quit watch mode.
 › Press Enter to trigger a test run.


  ● Test suite failed to run

thrown: [Error]

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarn test .  109.96s user 14.21s system 459% cpu 27.030 total
RUNS   @cloudflare/backstage-components  plugins/backstage-components/src/components/Cards/TeamRoles/CustomerSuccessCard.test.tsx
 RUNS   @cloudflare/backstage-app  packages/app/src/components/catalog/EntityFipsPicker/EntityFipsPicker.test.tsx

Test Suites: 2 failed, 23 passed, 25 of 65 total
Tests:       217 passed, 217 total
Snapshots:   0 total
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarn test .  110.85s user 14.04s system 463% cpu 26.974 total

No matter what Jest was doing, it always crashes after almost exactly 27 wallclock seconds. It literally didn’t matter what tests I selected or re-ran. Even the original problem, a bare yarn test (no tests selected, just hangs), will crash after 27 seconds:

Determining test suites to run...

  ● Test suite failed to run

thrown: [Error]

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarn test  2.05s user 0.71s system 10% cpu 27.094 total

Obviously, some sort of timeout. 27 seconds is kind of a weird number (unlike, say, 5 seconds or 60 seconds) but let’s try:

2025-03-19 15:09  find | fgrep 27
2025-03-19 15:09  git grep '\b27\b'

No decent hits.

How about something like 20+7 or even 20+5+2? Nope.

Googling/GPT-4oing  for “jest timeout 27 seconds” again yielded nothing useful. Far more people were having problems with testing asynchronously, or getting their tests to timeout, than with Jest proper. 

At this time, my colleague came back from his call, and with his help we determined some other things:

  • his system (MacOS) is not affected at all versus mine (Linux)

  • nvm use v20 didn’t fix it

  • I can reproduce it on a clean clone of github.com/backstage/backstage. The tests seem to progress further, about 50+ seconds. This lends credence to a running theory that the filesystem crawler/watcher is the one crashing, and backstage/backstage is a bigger repo than the internal Cloudflare instance, so it takes longer.

I next went on a little detour to grab another colleague who I know has been working on a Next.js project. He’s one of the few other people nearby who knows anything about Node.js. In my experience with troubleshooting it’s helpful to get multiple perspectives, so we can cover each other’s blind spots and avoid tunnel vision.

I then tried invoking many yarn tests in parallel, and I did manage to get the crash time to stretch out to 28 or 29 seconds if the system was under heavy load. So this tells me that it might not be a hard timeout but rather processing driven. A series of sleeps chugging along perhaps?

By now, there is a veritable crowd of curious onlookers gathered in front of my terminal marveling at the consistent 27 seconds crash and trading theories. At some point, someone asked if I had tried rebooting yet, and I had to sheepishly reply that I haven’t but “I’m absolutely sure it wouldn’t help whatsoever”.

And the astute reader can already guess that rebooting did nothing at all, or else this wouldn’t even be a story worth telling. Besides, haven’t I teased in the clickbaity title about some crazy Steam Locomotive from 1993?

Strace to the rescue

My colleague then put us back on track and suggested strace, and I decided to trace the simpler case of the idling menu (rather than trace running tests, which generated far more syscalls).

Watch Usage
 › Press a to run all tests.
 › Press f to run only failed tests.
 › Press o to only run tests related to changed files.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.
[], 1024, 1000)          = 0
openat(AT_FDCWD, "/proc/self/stat", O_RDONLY) = 21
read(21, "42375 (node) R 42372 42372 11692"..., 1023) = 301
close(21)                               = 0
epoll_wait(13, [], 1024, 0)             = 0
epoll_wait(13, [], 1024, 999)           = 0
openat(AT_FDCWD, "/proc/self/stat", O_RDONLY) = 21
read(21, "42375 (node) R 42372 42372 11692"..., 1023) = 301
close(21)                               = 0
epoll_wait(13, [], 1024, 0)             = 0
epoll_wait(13,

It basically epoll_waits until 27 seconds are up and then, right when the crash happens:

 ● Test suite failed to run                                                                                                                
                                                                                                                                            
thrown: [Error]                                                                                                                             
                                                                                                                                            
0x7ffd7137d5e0, 1024, 1000) = -1 EINTR (Interrupted system call)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=42578, si_uid=1000, si_status=1, si_utime=0, si_stime=0} ---
read(4, "*", 1)                     	= 1
write(15, "\210\352!\5\0\0\0\0\21\0\0\0\0\0\0\0", 16) = 16
write(5, "*", 1)                    	= 1
rt_sigreturn({mask=[]})             	= -1 EINTR (Interrupted system call)
epoll_wait(13, [{events=EPOLLIN, data={u32=14, u64=14}}], 1024, 101) = 1
read(14, "\210\352!\5\0\0\0\0\21\0\0\0\0\0\0\0", 512) = 16
wait4(42578, [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], WNOHANG, NULL) = 42578
rt_sigprocmask(SIG_SETMASK, ~[RTMIN RT_1], [], 8) = 0
read(4, "*", 1)                     	= 1
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x79e91e045330}, NULL, 8) = 0
write(5, "*", 1)                    	= 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
mmap(0x34ecad880000, 1495040, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x34ecad880000
madvise(0x34ecad880000, 1495040, MADV_DONTFORK) = 0
munmap(0x34ecad9ae000, 258048)      	= 0
mprotect(0x34ecad880000, 1236992, PROT_READ|PROT_WRITE) = 0

I don’t know about you, but sometimes I look at straces and wonder “Do people actually read this gibberish?” Fortunately, in the modern generative AI era, we can count on GPT-4o to gently chide: the process was interrupted EINTR by its child SIGCHLD, which means you forgot about the children, silly human. Is the problem with one of the cars rather than the engine?

Following this train of thought, I now re-ran with strace --follow-forks, which revealed a giant flurry of activity that promptly overflowed my terminal buffer. The investigation is really gaining steam now. The original trace weighs in at a hefty 500,000 lines, but here is a smaller equivalent version derived from a clean instance of backstage: trace.log.gz. I have uploaded this trace here because the by-now overhyped Steam Locomotive is finally making its grand appearance and I know there’ll be people who’d love nothing more than to crawl through a haystack of system calls looking for a train-sized needle. Consider yourself lucky, I had to do it without even knowing what I was looking for, much less that it was a whole Steam Locomotive.


This section is left intentionally blank to allow locomotive enthusiasts who want to find the train on their own to do so first.


Remember my comment about straces being gibberish? Actually, I was kidding. So there are a few ways to make it more manageable, and with experience you’ll learn which system calls to pay attention to, such as execve, chdir, open, read, fork, and signals, and which ones to skim over, such as mprotect, mmap, and futex.

Since I’m writing this account after the fact, let’s cheat a little and assume I was super smart and zeroed in on execve correctly on the first try:

🌈  ~  zgrep execve trace.log.gz | head
execve("/home/yew/.nvm/versions/node/v18.20.6/bin/yarn", ["yarn", "test", "steam-regulator"], 0x7ffdff573148 /* 72 vars */) = 0
execve("/home/yew/.pyenv/shims/node", ["node", "/home/yew/.nvm/versions/node/v18"..., "test", "steam-regulator"], 0x7ffd64f878c8 /* 72 vars */) = -1 ENOENT (No such file or directory)
execve("/home/yew/.pyenv/bin/node", ["node", "/home/yew/.nvm/versions/node/v18"..., "test", "steam-regulator"], 0x7ffd64f878c8 /* 72 vars */) = -1 ENOENT (No such file or directory)
execve("/home/yew/repos/secrets/bin/node", ["node", "/home/yew/.nvm/versions/node/v18"..., "test", "steam-regulator"], 0x7ffd64f878c8 /* 72 vars */) = -1 ENOENT (No such file or directory)
execve("/home/yew/.nvm/versions/node/v18.20.6/bin/node", ["node", "/home/yew/.nvm/versions/node/v18"..., "test", "steam-regulator"], 0x7ffd64f878c8 /* 72 vars */) = 0
[pid 49307] execve("/bin/sh", ["/bin/sh", "-c", "backstage-cli repo test resource"...], 0x3d17d6d0 /* 156 vars */ <unfinished ...>
[pid 49307] <... execve resumed>)   	= 0
[pid 49308] execve("/home/yew/cloudflare/repos/backstage/node_modules/.bin/backstage-cli", ["backstage-cli", "repo", "test", "steam-regulator"], 0x5e7ef80051d8 /* 156 vars */ <unfinished ...>
[pid 49308] <... execve resumed>)   	= 0
[pid 49308] execve("/tmp/yarn--1742459197616-0.9027914591640542/node", ["node", "/home/yew/cloudflare/repos/backs"..., "repo", "test", "steam-regulator"], 0x7ffcc18af270 /* 156 vars */) = 0
🌈  ~  zgrep execve trace.log.gz | wc -l
2254

Phew, 2,000 is a lot of execves . Let’s get the unique ones, plus their counts:

🌈  ~  zgrep -oP '(?<=execve\(")[^"]+' trace.log.gz | xargs -L1 basename | sort | uniq -c | sort -nr
    576 watchman
    576 hg
    368 sl
    358 git
     16 sl.actual
     14 node
      2 sh
      1 yarn
      1 backstage-cli

Have you spotted the Steam Locomotive yet? I spotted it immediately because this is My Own System and Surely This Means I Am Perfectly Aware Of Everything That Is Installed Unlike, er, node_modules.

sl  is actually a fun little joke program from 1993 that plays on users’ tendencies to make a typo on ls. When sl  runs, it clears your terminal to make way for an animated steam locomotive to come chugging through.

                        (  ) (@@) ( )  (@)  ()	@@	O 	@ 	O 	@  	O
                   (@@@)
               (	)
            (@@@@)
 
          (   )
      ====    	________            	___________
  _D _|  |_______/    	\__I_I_____===__|_________|
   |(_)---  |   H\________/ |   |    	=|___ ___|  	_________________
   / 	|  |   H  |  | 	|   |     	||_| |_|| 	_|            	\_____A
  |  	|  |   H  |__--------------------| [___] |   =|                    	|
  | ________|___H__/__|_____/[][]~\_______|   	|   -|                    	|
  |/ |   |-----------I_____I [][] []  D   |=======|____|________________________|_
__/ =| o |=-~~\  /~~\  /~~\  /~~\ ____Y___________|__|__________________________|_
 |/-=|___|=O=====O=====O=====O   |_____/~\___/      	|_D__D__D_|  |_D__D__D_|
  \_/  	\__/  \__/  \__/  \__/  	\_/           	\_/   \_/	\_/   \_/

When I first saw that Jest was running sl so many times, my first thought was to ask my colleague if sl is a valid command on his Mac, and of course it is not. After all, which serious engineer would stuff their machine full of silly commands like sl, gti, cowsay, or toilet ? The next thing I tried was to rename sl to something else, and sure enough all my problems disappeared: yarn test started working perfectly.

So what does Jest have to do with Steam Locomotives?

Nothing, that’s what. The whole affair is an unfortunate naming clash between sl the Steam Locomotive and sl the Sapling CLI. Jest wanted sl the source control system, but ended up getting steam-rolled by sl the Steam Locomotive.


Fortunately the devs took it in good humor, and made a (still unreleased) fix. Check out the train memes!



At this point the main story has ended. However, there are still some unresolved nagging questions, like…

How did the crash arrive at the magic number of a relatively even 27 seconds?

I don’t know. Actually I’m not sure if a forked child executing sl still has a terminal anymore, but the travel time of the train does depend on the terminal width. The wider it is, the longer it takes:

🌈  ~  tput cols
425
🌈  ~  time sl
sl  0.19s user 0.06s system 1% cpu 20.629 total
🌈  ~  tput cols
58
🌈  ~  time sl  
sl  0.03s user 0.01s system 0% cpu 5.695 total

So the first thing I tried was to run yarn test in a ridiculously narrow terminal and see what happens:

Determin
ing test
 suites 
to run..
.       
        
  ● Test
 suite f
ailed to
 run    
        
thrown: 
[Error] 
        
error Co
mmand fa
iled wit
h exit c
ode 1.  
info Vis
it https
://yarnp
kg.com/e
n/docs/c
li/run f
or docum
entation
 about t
his comm
and.    
yarn tes
t  1.92s
 user 0.
67s syst
em 9% cp
u 27.088
 total  
🌈  back
stage [m
aster] t
put cols
        
8

Alas, the terminal width doesn’t affect jest at all. Jest calls sl via execa so let’s mock that up locally:

🌈  choochoo  cat runSl.mjs 
import {execa} from 'execa';
const { stdout } = await execa('tput', ['cols']);
console.log('terminal colwidth:', stdout);
await execa('sl', ['root']);
🌈  choochoo  time node runSl.mjs
terminal colwidth: 80
node runSl.mjs  0.21s user 0.06s system 4% cpu 6.730 total

So execa uses the default terminal width of 80, which takes the train 6.7 seconds to cross. And 27 seconds divided by 6.7 is awfully close to 4. So is Jest running sl 4 times? Let’s do a poor man’s bpftrace by hooking into sl like so:

#!/bin/bash

uniqid=$RANDOM
echo "$(date --utc +"%Y-%m-%d %H:%M:%S.%N") $uniqid started" >> /home/yew/executed.log
/usr/games/sl.actual "$@"
echo "$(date --utc +"%Y-%m-%d %H:%M:%S.%N") $uniqid ended" >> /home/yew/executed.log

And if we check executed.log, sl is indeed executed in 4 waves, albeit by 5 workers simultaneously in each wave:

#wave1
2025-03-20 13:23:57.125482563 21049 started
2025-03-20 13:23:57.127526987 21666 started
2025-03-20 13:23:57.131099388 4897 started
2025-03-20 13:23:57.134237754 102 started
2025-03-20 13:23:57.137091737 15733 started
#wave1 ends, wave2 starts
2025-03-20 13:24:03.704588580 21666 ended
2025-03-20 13:24:03.704621737 21049 ended
2025-03-20 13:24:03.707780748 4897 ended
2025-03-20 13:24:03.712086346 15733 ended
2025-03-20 13:24:03.711953000 102 ended
2025-03-20 13:24:03.714831149 18018 started
2025-03-20 13:24:03.721293279 23293 started
2025-03-20 13:24:03.724600164 27918 started
2025-03-20 13:24:03.729763900 15091 started
2025-03-20 13:24:03.733176122 18473 started
#wave2 ends, wave3 starts
2025-03-20 13:24:10.294286746 18018 ended
2025-03-20 13:24:10.297261754 23293 ended
2025-03-20 13:24:10.300925031 27918 ended
2025-03-20 13:24:10.300950334 15091 ended
2025-03-20 13:24:10.303498710 24873 started
2025-03-20 13:24:10.303980494 18473 ended
2025-03-20 13:24:10.308560194 31825 started
2025-03-20 13:24:10.310595182 18452 started
2025-03-20 13:24:10.314222848 16121 started
2025-03-20 13:24:10.317875812 30892 started
#wave3 ends, wave4 starts
2025-03-20 13:24:16.883609316 24873 ended
2025-03-20 13:24:16.886708598 18452 ended
2025-03-20 13:24:16.886867725 31825 ended
2025-03-20 13:24:16.890735338 16121 ended
2025-03-20 13:24:16.893661911 21975 started
2025-03-20 13:24:16.898525968 30892 ended
#crash imminent! wave4 ending, wave5 starting...
2025-03-20 13:24:23.474925807 21975 ended

The logs were emitted for about 26.35 seconds, which is close to 27. It probably crashed just as wave4 was reporting back. And each wave lasts about 6.7 seconds, right on the money with manual measurement. 

So why is Jest running sl in 4 waves? Why did it crash at the start of the 5th wave?

Let’s again modify the poor man’s bpftrace to also log the args and working directory:

echo "$(date --utc +"%Y-%m-%d %H:%M:%S.%N") $uniqid started: $@ at $PWD" >> /home/yew/executed.log

From the results we can see that the 5 workers are busy executing sl root, which corresponds to the getRoot()  function in jest-change-files/sl.ts

2025-03-21 05:50:22.663263304  started: root at /home/yew/cloudflare/repos/backstage/packages/app/src
2025-03-21 05:50:22.665550470  started: root at /home/yew/cloudflare/repos/backstage/packages/backend/src
2025-03-21 05:50:22.667988509  started: root at /home/yew/cloudflare/repos/backstage/plugins/access/src
2025-03-21 05:50:22.671781519  started: root at /home/yew/cloudflare/repos/backstage/plugins/backstage-components/src
2025-03-21 05:50:22.673690514  started: root at /home/yew/cloudflare/repos/backstage/plugins/backstage-entities/src
2025-03-21 05:50:29.247573899  started: root at /home/yew/cloudflare/repos/backstage/plugins/catalog-types-common/src
2025-03-21 05:50:29.251173536  started: root at /home/yew/cloudflare/repos/backstage/plugins/cross-connects/src
2025-03-21 05:50:29.255263605  started: root at /home/yew/cloudflare/repos/backstage/plugins/cross-connects-backend/src
2025-03-21 05:50:29.257293780  started: root at /home/yew/cloudflare/repos/backstage/plugins/pingboard-backend/src
2025-03-21 05:50:29.260285783  started: root at /home/yew/cloudflare/repos/backstage/plugins/resource-insights/src
2025-03-21 05:50:35.823374079  started: root at /home/yew/cloudflare/repos/backstage/plugins/scaffolder-backend-module-gaia/src
2025-03-21 05:50:35.825418386  started: root at /home/yew/cloudflare/repos/backstage/plugins/scaffolder-backend-module-r2/src
2025-03-21 05:50:35.829963172  started: root at /home/yew/cloudflare/repos/backstage/plugins/security-scorecard-dash/src
2025-03-21 05:50:35.832597778  started: root at /home/yew/cloudflare/repos/backstage/plugins/slo-directory/src
2025-03-21 05:50:35.834631869  started: root at /home/yew/cloudflare/repos/backstage/plugins/software-excellence-dashboard/src
2025-03-21 05:50:42.404063080  started: root at /home/yew/cloudflare/repos/backstage/plugins/teamcity/src

The 16 entries here correspond neatly to the 16 rootDirs configured in Jest for Cloudflare’s backstage. We have 5 trains, and we want to visit 16 stations so let’s do some simple math. 16/5.0 = 3.2 which means our trains need to go back and forth 4 times at a minimum to cover them all.

Final mystery: Why did it crash?

Let’s go back to the very start of our journey. The original [Error] thrown was actually from here and after modifying node_modules/jest-changed-files/index.js, I found that the error is shortMessage: 'Command failed with ENAMETOOLONG: sl status...‘  and the reason why became clear when I interrogated Jest about what it thinks the repos are.

While the git repo is what you’d expect, the sl “repo” looks amazingly like a train wreck in motion:

got repos.git as Set(1) { '/home/yew/cloudflare/repos/backstage' }
got repos.sl as Set(1) {
  '\x1B[?1049h\x1B[1;24r\x1B[m\x1B(B\x1B[4l\x1B[?7h\x1B[?25l\x1B[H\x1B[2J\x1B[15;80H_\x1B[15;79H_\x1B[16d|\x1B[9;80H_\x1B[12;80H|\x1B[13;80H|\x1B[14;80H|\x1B[15;78H__/\x1B[16;79H|/\x1B[17;80H\\\x1B[9;
  79H_D\x1B[10;80H|\x1B[11;80H/\x1B[12;79H|\x1B[K\x1B[13d\b|\x1B[K\x1B[14d\b|/\x1B[15;1H\x1B[1P\x1B[16;78H|/-\x1B[17;79H\\_\x1B[9;1H\x1B[1P\x1B[10;79H|(\x1B[11;79H/\x1B[K\x1B[12d\b\b|\x1B[K\x1B[13d\b|
  _\x1B[14;1H\x1B[1P\x1B[15;76H__/ =\x1B[16;77H|/-=\x1B[17;78H\\_/\x1B[9;77H_D _\x1B[10;78H|(_\x1B[11;78H/\x1B[K\x1B[12d\b\b|\x1B[K\x1B[13d\b| _\x1B[14;77H|/ |\x1B[15;75H__/
  =|\x1B[16;76H|/-=|\x1B[17;1H\x1B[1P\x1B[8;80H=\x1B[9;76H_D _|\x1B[10;77H|(_)\x1B[11;77H/\x1B[K\x1B[12d\b\b|\x1B[K\x1B[13d\b|
  _\r\x1B[14d\x1B[1P\x1B[15d\x1B[1P\x1B[16;75H|/-=|_\x1B[17;1H\x1B[1P\x1B[8;79H=\r\x1B[9d\x1B[1P\x1B[10;76H|(_)-\x1B[11;76H/\x1B[K\x1B[12d\b\b|\x1B[K\x1B[13d\b| _\r\x1B[14d\x1B[1P\x1B[15;73H__/ =|
  o\x1B[16;74H|/-=|_\r\x1B[17d\x1B[1P\x1B[8;78H=\r\x1B[9d\x1B[1P\x1B[10;75H|(_)-\x1B[11;75H/\x1B[K\x1B[12d\b\b|\x1B[K\x1B[13d\b|
  _\r\x1B[14d\x1B[1P\x1B[15d\x1B[1P\x1B[16;73H|/-=|_\r\x1B[17d\x1B[1P\x1B[8;77H=\x1B[9;73H_D _|  |\x1B[10;74H|(_)-\x1B[11;74H/     |\x1B[12;73H|      |\x1B[13;73H| _\x1B[14;73H|/ |   |\x1B[15;71H__/
  =| o |\x1B[16;72H|/-=|___|\x1B[17;1H\x1B[1P\x 1B[5;79H(@\x1B[7;77H(\r\x1B[8d\x1B[1P\x1B[9;72H_D _|  |_\x1B[10;1H\x1B[1P\x1B[11d\x1B[1P\x1B[12d\x1B[1P\x1B[13;72H| _\x1B[14;72H|/ |   |-\x1B[15;70H__/
  =| o |=\x1B[16;71H|/-=|___|=\x1B[17;1H\x1B[1P\x1B[8d\x1B[1P\x1B[9;71H_D _|  |_\r\x1B[10d\x1B[1P\x1B[11d\x1B[1P\x1B[12d\x1B[1P\x1B[13;71H| _\x1B[14;71H|/ |   |-\x1B[15;69H__/ =| o
  |=-\x1B[16;70H|/-=|___|=O\x1B[17;71H\\_/      \\\x1B[8;1H\x1B[1P\x1B[9;70H_D _|  |_\x1B[10;71H|(_)---  |\x1B[11;71H/     |  |\x1B[12;70H|      |  |\x1B[13;70H| _\x1B[80G|\x1B[14;70H|/ |
  |-\x1B[15;68H__/ =| o |=-~\x1B[16;69H|/-=|___|=\x1B[K\x1B[17;70H\\_/      \\O\x1B[8;1H\x1B[1P\x1B[9;69H_D _|  |_\r\x1B[10d\x1B[1P\x1B[11d\x1B[1P\x1B[12d\x1B[1P\x1B[13;69H| _\x1B[79G|_\x1B[14;69H|/ |
  |-\x1B[15;67H__/ =| o |=-~\r\x1B[16d\x1B[1P\x1B[17;69H\\_/      \\_\x1B[4d\b\b(@@\x1B[5;75H(    )\x1B[7;73H(@@@)\r\x1B[8d\x1B[1P\x1B[9;68H_D _|
  |_\r\x1B[10d\x1B[1P\x1B[11d\x1B[1P\x1B[12d\x1B[1P\x1B[13;68H| _\x1B[78G|_\x1B[14;68H|/ |   |-\x1B[15;66H__/ =| o |=-~~\\\x1B[16;67H|/-=|___|=   O\x1B[17;68H\\_/ \\__/\x1B[8;1H\x1B[1P\x1B[9;67H_D _|
  |_\r\x1B[10d\x1B[1P\x1B[11d\x1B[1P\x1B[12d\x1B[1P\x1B[13;67H| _\x1B[77G|_\x1B[14;67H|/ |   |-\x1B[15;65H__/ =| o |=-~O==\x1B[16;66H|/-=|___|= |\x1B[17;1H\x1B[1P\x1B[8d\x1B[1P\x1B[9;66H_D _|
  |_\x1B[10;67H|(_)---  |   H\x1B[11;67H/     |  |   H\x1B[12;66H|      |  |   H\x1B[13;66H| _\x1B[76G|___H\x1B[14;66H|/ |   |-\x1B[15;64H__/ =| o |=-O==\x1B[16;65H|/-=|___|=
  |\r\x1B[17d\x1B[1P\x1B[8d\x1B[1P\x1B[9;65H_D _|  |_\x1B[80G/\x1B[10;66H|(_)---  |   H\\\x1B[11;1H\x1B[1P\x1B[12d\x1B[1P\x1B[13;65H| _\x1B[75G|___H_\x1B[14;65H|/ | |-\x1B[15;63H__/ =| o |=-~~\\
  /\x1B[16;64H|/-=|___|=O=====O\x1B[17;65H\\_/      \\__/  \\\x1B[1;4r\x1B[4;1H\n' + '\x1B[1;24r\x1B[4;74H(    )\x1B[5;71H(@@@@)\x1B[K\x1B[7;69H(   )\x1B[K\x1B[8;68H====
  \x1B[80G_\x1B[9;1H\x1B[1P\x1B[10;65H|(_)---  |   H\\_\x1B[11;1H\x1B[1P\x1B[12d\x1B[1P\x1B[13;64H| _\x1B[74G|___H_\x1B[14;64H|/ |   |-\x1B[15;62H__/ =| o |=-~~\\  /~\x1B[16;63H|/-=|___|=
  ||\x1B[K\x1B[17;64H\\_/      \\O=====O\x1B[8;67H==== \x1B[79G_\r\x1B[9d\x1B[1P\x1B[10;64H|(_)---  |   H\\_\x1B[11;64H/     |  |   H  |\x1B[12;63H|      |  |   H  |\x1B[13;63H|
  _\x1B[73G|___H__/\x1B[14;63H|/ |   |-\x1B[15;61H__/ =| o |=-~~\\  /~\r\x1B[16d\x1B[1P\x1B[17;63H\\_/      \\_\x1B[8;66H==== \x1B[78G_\r\x1B[9d\x1B[1P\x1B[10;63H|(_)---  |
  H\\_\r\x1B[11d\x1B[1P\x1B[12;62H|      |  |   H  |_\x1B[13;62H| _\x1B[72G|___H__/_\x1B[14;62H|/ |   |-\x1B[15;60H__/ =| o |=-~~\\  /~~\\\x1B[16;61H|/-=|___|=   O=====O\x1B[17;62H\\_/      \\__/
  \\__/\x1B[8;65H==== \x1B[77G_\r\x1B[9d\x1B[1P\x1B[10;62H|(_)---  |   H\\_\r\x1B[11d\x1B[1P\x1B[12;61H|      |  |   H  |_\x1B[13;61H| _\x1B[71G|___H__/_\x1B[14;61H|/ |   |-\x1B[80GI\x1B[15;59H__/ =|
  o |=-~O=====O==\x1B[16;60H|/-=|___|=    ||    |\x1B[17;1H\x1B[1P\x1B[2;79H(@\x1B[3;74H(   )\x1B[K\x1B[4;70H(@@@@)\x1B[K\x1B[5;67H(    )\x1B[K\x1B[7;65H(@@@)\x1B[K\x1B[8;64H====
  \x1B[76G_\r\x1B[9d\x1B[1P\x1B[10;61H|(_)---  |   H\\_\x1B[11;61H/     |  |   H  |  |\x1B[12;60H|      |  |   H  |__-\x1B[13;60H| _\x1B[70G|___H__/__|\x1B[14;60H|/ |   |-\x1B[79GI_\x1B[15;58H__/ =| o
  |=-O=====O==\x1B[16;59H|/-=|___|=    ||    |\r\x1B[17d\x1B[1P\x1B[8;63H==== \x1B[75G_\r\x1B[9d\x1B[1P\x1B[10;60H|(_)---  |   H\\_\r\x1B[11d\x1B[1P\x1B[12;59H|      |  |   H  |__-\x1B[13;59H|
  _\x1B[69G|___H__/__|_\x1B[14;59H|/ |   |-\x1B[78GI_\x1B[15;57H__/ =| o |=-~~\\  /~~\\  /\x1B[16;58H|/-=|___|=O=====O=====O\x1B[17;59H\\_/      \\__/  \\__/  \\\x1B[8;62H====
  \x1B[74G_\r\x1B[9d\x1B[1P\x1B[10;59H|(_)---  |   H\\_\r\x1B  |  |   H  |__-\x1B[13;58H| _\x1B[68G|___H__/__|_\x1B[14;58H|/ |   |-\x1B[77GI_\x1B[15;56H__/ =| o |=-~~\\ /~~\\  /~\x1B[16;57H|/-=|___|=
  ||    ||\x1B[K\x1B[17;58H\\_/      \\O=====O=====O\x1B[8;61H==== \x1B[73G_\r\x1B[9d\x1B[1P\x1B[10;58H|(_)---    _\x1B[67G|___H__/__|_\x1B[14;57H|/ |   |-\x1B[76GI_\x1B[15;55H__/ =| o |=-~~\\  /~~\\
  /~\r\x1B[16d\x1B[1P\x1B[17;57H\\_/      \\_\x1B[2;75H(  ) (\x1B[3;70H(@@@)\x1B[K\x1B[4;66H()\x1B[K\x1B[5;63H(@@@@)\x1B[

Acknowledgements

Thank you to my colleagues Mengnan Gong and Shuhao Zhang, whose ideas and perspectives helped narrow down the root causes of this mystery.

If you enjoy troubleshooting weird and tricky production issues, our engineering teams are hiring.

A Rebirth of a Cursed Existence? – The Babuk Locker 2.0

Post Syndicated from Rapid7 original https://blog.rapid7.com/2025/04/02/a-rebirth-of-a-cursed-existence-the-babuk-locker-2-0/

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0

Co-authored by Yaniv Allender and Anna Sirokova

A Rebirth of a Cursed Existence? Examining ‘Babuk Locker 2.0’ Ransomware

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0

Introduction

Ransomware remains a major threat, causing significant disruption and financial losses to organizations across various sectors. Cybercriminal groups behind these attacks constantly adapt their methods to maximize damage and profit.

At Rapid7, we actively monitor new cyber threats, keeping an eye on ransomware groups and their changing tactics. In early 2025, we came across a channel promoting itself as Babuk Locker. Since the original group had shut down in 2021, we decided to investigate whether this was a rebrand or a new threat. Several underground forums and Telegram channels started mentioning ‘Babuk Locker 2.0,’ with some actors taking credit for recent attacks. Since Babuk’s leaked source code in 2021 had led to many spin-off ransomware strains, we wanted to find out whether this was a real comeback or just another group using Babuk’s name.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 1 – Online discourse against Bjorka as a scammer
A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 2 – Online discourse against Bjorka and SkyWave as scammers

We started by gathering intelligence from dark web marketplaces, hacker forums, and private Telegram groups. We saw a rise in discussions about Babuk’s return, often linked to two groups, ‘Skywave’ and ‘Bjorka.’ These actors claimed responsibility for major attacks, and their leak sites suggested they might be working with other cybercriminal groups.

This blog delves into the potential revival of Babuk Locker 2.0, its alleged operators, and their activities. We analyze the involvement of ‘Skywave’ and ‘Bjorka,’ their claimed victims, and the evolution of Babuk’s Ransomware-as-a-Service (RaaS) model. Our findings include technical analysis, victimology, and the broader risks posed by this campaign.

Operators: Skywave and Bjorka

While monitoring Babuk Locker 2.0 activity, we identified two key groups linked to its operations—Skywave and Bjorka. These groups frequently appeared in discussions on underground forums and Telegram channels, claiming responsibility for attacks and promoting Babuk-related leaks. Our analysis suggests that these groups play a significant role in Babuk Locker 2.0’s activities, either as affiliates or key operators.

Skywave

Skywave is a recently identified threat actor known for allegedly executing cyberattacks against various high-profile organizations and government agencies. Their operations have raised concerns within the cybersecurity community due to the sensitivity and volume of the data reportedly compromised, as well as the anonymity of the operator. Skywave is suspected of operating multiple Telegram channels under different aliases, some of which have been flagged as scams and removed by Telegram.

The specific TTPs employed by Skywave remain undisclosed, leaving room for speculation regarding their infiltration and data exfiltration methods. Since late 2024, Skywave has maintained its presence on various platforms, such as Telegram, DarkForums, and the dedicated Babuk Locker 2.0 DLS, where they have been sharing leaked data from their allegedly recent attacks. Victim lists indicate a focus on high-profile organizations with sensitive data.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 3 – The Telegram user of Skywave

Bjorka

Bjorka is a threat actor mainly known for allegedly breaching Indonesian government and citizen data, often leaking sensitive information as a form of hacktivism. The alias gained prominence in 2022 with a series of high-profile data leaks, first making headlines in March by exposing over 105 million Indonesian voter records. Throughout 2022, Bjorka targeted multiple institutions, leaking personal data to highlight security flaws and criticize policies. By August 2022, Bjorka joined BreachForums, where they are sharing large databases from breached telecom services. Authorities attempted to identify the hacker, even arresting an individual, but Bjorka mocked the effort, claiming the wrong person was caught. The threat actor is active on BreachForums and Telegram and owns a personal leak site (netleaks[.]net) to distribute stolen data and engage followers.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 4 – The Telegram user of Bjorka

Babuk Locker 2.0/Babuk-Bjorka

Since February 2025, Skywave has claimed ownership on at least 5 different Telegram channels and posts daily about their previous and current victims. Throughout the research, we found dozens of newly created Telegram channels with the names ‘Babuk Locker 2.0’, ‘Babuk 2.0 Ransomware Affiliates’, etc. Some of which overlapped with one another. Additionally, several channels were labeled as scams by Telegram itself and were unavailable a couple of days after they were created.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 5 – A Babuk Locker Telegram channel labeled as a scam by the platform

During our research, we noticed the consistent amplification of the Babuk 2.0 content by Bjorka on their Telegram channel. Speculation about the possible affiliation between Babuk and Bjorka rose due to the overlap of victims, such as the case of ‘Hindustan Aerospace & Engineering’ from India. The organization was initially reported as a victim of Bjorka in December 2023, and again as a victim of Babuk as of March 2025.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 6 – Overlap of victimology between Bjorka and Babuk 2.0

Further evidence of a possible collaboration between the threat actors emerges from the ‘Contact Us’ tab on Babuk’s DLS, where the logos of Skywave and Bjorka appear next to each other, as well as another possible affiliate named GD Locker Sec.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 7 – The ‘Contact US’ tab on the DLS of Babuk, showing the logos of Bjorka and Skywave

Technical Analysis

A sample named babuk.exe SHA-256 3facc153ed82a72695ee2718084db91f85e2560407899e1c7f6938fd4ea011e9 was initially shared on the Telegram channel “Babuk 2.0 Ransomware Affiliates”, before being forwarded to another operational account. Upon analysis, it turned out not to be Babuk Locker at all, but rather LockBit 3.0 also known as LockBit Black. This case is yet another example of the well-established trend: threat actors rebranding ransomware strains, whether to confuse researchers, lure affiliates, or just keep the marketing fresh. Either way, babuk.exe is just LockBit 3.0/Black wearing a fake name.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 8 – “Babuk” sample shared on Babuk 2.0 Affiliate Group Telegram channel

LockBit 3.0 Overview

LockBit 3.0/Black, is a ransomware variant that shares similarities with BlackMatter ransomware. On September 21, 2022, a user named @ali_qushji leaked the LockBit 3.0 builder on Twitter. The leak code made it easy for the least skilled attackers to join the game.

Encryption Methods

An analyzed sample of LockBit 3.0 uses a combination of AES-256 and RSA-2048 encryption. AES-256 is used to encrypt victim files and RSA-2048 encryption used to encrypt the AES key, ensuring decryption is impossible without the attacker’s private key.

Terminated Processes and services

LockBit 3.0 terminates various applications and system processes (the full list is in the table below) most likely to maximize encryption efficiency and prevent file access conflicts. It also disables key security and backup services to limit recovery possibilities and increase impact.

Terminated Processes Terminated Services
sql vss
oracle sql
ocssd svc
dbsnmp memtas
synctime mepocs
agntsvc msexchange
isqlplussvc sophos
xfssvccon veeam
mydesktopservice backup
ocautoupds GxVss
encsvc GxBlr
firefox GxFWD
tbirdconfig GxCVD
mydesktopqos GxCIMgr
ocomm
dbeng50
sqbcoreservice
excel
infopath
msaccess
mspu
onenote
outlook
powerpnt
steam
thebat
thunderbird
visio
winword
wordpad
notepad
calc
wuauclt
onedrive

Active Directory Enumeration

LockBit 3.0 uses logoncli_DsGetDcNameW API function used for Active Directory (AD) enumeration. To brute-force AD accounts, analyzed LockBit 3.0 sample came preloaded with Base64-encoded username and password combinations decoded and listed below.

Username Password
bad.lab Qwerty
Administrator 123QWEqwe
@#Admin2 P@ssw0rd
Administrator P@ssw0rd
Administrator Qwerty
Administrator 123QWEqwe
Administrator 123QWEqweqwe

Babuk or LockBit 3.0? Rebranding Won’t Change the Code.

Analysis confirms that babuk.exe, advertised in the Babuk 2.0 Ransomware Affiliates Telegram channel, is actually based entirely on LockBit 3.0 source code—not Babuk. The sample shows key techniques identical to previous LockBit 3.0 variants, reinforcing that this is yet another case of threat actors rebranding existing ransomware rather than introducing anything genuinely new.

Key Overlapping Techniques

The analyzed sample uses API harvesting by hashing API names from DLLs and comparing them against a predefined list of required APIs (Figure 7). This technique, likely to obfuscate API calls and evade detection, mirrors the approach seen in Lockbit3.0/Black and aligns with previous findings by Trend Micro.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 9 – LockBit 3.0’s routine for API harvesting function comparison—our analyzed sample (left) vs. TrendMicro’s reported sample (right).

Likewise, The XOR key 0x4803BFC7 LockBit 3.0 used for renaming APIs is the same as it was reported before. The xor key is re-used multiple times in the code.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 10 – 0x4803BFC7 xor key observed in analyzed sample

Additionally, the ransom note creating routine is identical as in previous Lockbit3.0/Black samples.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 11 – readme creation routine

Like previous LockBit 3.0/ Black samples, the analyzed variant modifies the desktop wallpaper to display a ransom note—branded, unsurprisingly, as “LockBit Black” (not Babuk, in case anyone was still confused). It also appends specific extensions to encrypted files, changes their icons, and drops a .ico file in the %PROGRAMDATA% directory, staying true to the LockBit playbook.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 12 – Lockbit3.0 wallpaper and ransom note

The ransom note referenced “Orion Hackers” and the tox ID 32C12B278912E26E5EAC57AEBB3F4FF16F0E31603C7B9D46AC02E9D993EE14351CEC3AB5945C. A search on this TOX ID linked the ransom demands to the `Babuk 2.0 Affiliate Group` on Telegram. Additionally, we discovered that messages from this channel were being reposted by an actor named Bjorkanism, who is actively sharing content from Affiliate Group Babuk 2.0 which is actually leaked Lockbit3.0.

Victimology

The new Babuk Locker 2.0 has recently been making waves within the cybersecurity and intelligence scene, claiming dozens of high-profile cyberattacks in a short time of less than two months of operation. Since January 2025, the group has listed at least 100 organizations as their alleged victims. Among their alleged victims are Amazon, the Israeli Knesset, Sodexo, and other high-profile organizations. Victims are from multiple sectors including energy, manufacturing, IT, government, etc.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 13 – Victims listed on the Babuk Locker 2.0 DLS
A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 14 – Babuk Locker 2.0 victims per country

There have been growing claims of overlaps between Babuk Locker 2.0 and other ransomware groups, as some of their alleged victims were already attacked by other groups, such as HellCat, RansomHub, FunkSec, and others. These overlaps in victimology reinforce concerns about the authenticity of the new Babuk group entity and its operations.

A Rebirth of a Cursed Existence? - The Babuk Locker 2.0
Figure 15 – Babuk Locker 2.0 victims overlap with another ransomware group

Conclusion

Babuk Locker 2.0 is not a true revival of the original Babuk group—it’s just LockBit 3.0 with a new label. Our analysis strongly suggests that Skywave and Bjorka are behind this operation, either as collaborators or opportunistic actors riding the same wave.

Despite its bold claims, Babuk 2.0’s victim list overlaps heavily with other ransomware groups, raising doubts about the legitimacy of its attacks. Rather than a sophisticated new threat, this looks more like a rebranding stunt—a common tactic among ransomware operators to confuse defenders, attract affiliates, and inflate their reputation.

This case reinforces a familiar pattern: ransomware groups don’t disappear—they just change names, recycle code, and keep cashing in. Whether Skywave and Bjorka are working together or simply using Babuk’s name for credibility, one thing is clear: Babuk 2.0 is just LockBit 3.0 in a different costume.

IOCs (Indicators of Compromise)

DLS (Data Leak Sites)
7dikawx73goypgfi4zyo5fcajxwb7agemmiwqax3p54aey4dwobcvcyd.onion
imblth46g3x5oo444wkjn7umj4g26tnhmrlo53ovfqmmkmughdw4j2ad.onion
bxwu33iefqfc3rxigynn3ghvq4gdw3gxgxna5m4aa3o4vscdeeqhiqad.onion
Telegram Handles
@OfficialBabukLocker
@BabukLockerRaasSHA1
@BabukLockerRaas (inactive)
@BGLocker
Tox ID & Contact
Tox: 022A7EEB83B648F55DA7A6BEFD130C2156C74F3501A31D853234EC2D18E77A1E5BEC7F60201
Email: [email protected]
YouTube: youtube.com/@babuklocker
Ransomware samples obtained from Telegram channels
3facc153ed82a72695ee2718084db91f85e2560407899e1c7f6938fd4ea011e9
bdc482583a330a4682d13bfb7a0cf75b2fa350ac536064bce7b2bdd9d875de4a
0192eaf2ea5a52fa9d2398b3a2f69c163d47b368cd131ccae60df0a98c1fa2ca

Rational Astrologies and Security

Post Syndicated from Bruce Schneier original https://www.schneier.com/blog/archives/2025/04/rational-astrologies-and-security.html

John Kelsey and I wrote a short paper for the Rossfest Festschrift: “Rational Astrologies and Security“:

There is another non-security way that designers can spend their security budget: on making their own lives easier. Many of these fall into the category of what has been called rational astrology. First identified by Randy Steve Waldman [Wal12], the term refers to something people treat as though it works, generally for social or institutional reasons, even when there’s little evidence that it works—­and sometimes despite substantial evidence that it does not.

[…]

Both security theater and rational astrologies may seem irrational, but they are rational from the perspective of the people making the decisions about security. Security theater is often driven by information asymmetry: people who don’t understand security can be reassured with cosmetic or psychological measures, and sometimes that reassurance is important. It can be better understood by considering the many non-security purposes of a security system. A monitoring bracelet system that pairs new mothers and their babies may be security theater, considering the incredibly rare instances of baby snatching from hospitals. But it makes sense as a security system designed to alleviate fears of new mothers [Sch07].

Rational astrologies in security result from two considerations. The first is the principal­-agent problem: The incentives of the individual or organization making the security decision are not always aligned with the incentives of the users of that system. The user’s well-being may not weigh as heavily on the developer’s mind as the difficulty of convincing his boss to take a chance by ignoring an outdated security rule or trying some new technology.

The second consideration that can lead to a rational astrology is where there is a social or institutional need for a solution to a problem for which there is actually not a particularly good solution. The organization needs to reassure regulators, customers, or perhaps even a judge and jury that “they did all that could be done” to avoid some problem—even if “all that could be done” wasn’t very much.

Meet the AWS News Blog team!

Post Syndicated from Channy Yun (윤석찬) original https://aws.amazon.com/blogs/aws/meet-the-aws-news-blog-team/

Now that Jeff Barr has retired from the AWS News Blog as of December last year, the AWS News Blog team will keep sharing the most important and impactful AWS product launches the moment they become available. I want to quote Jeff’s last comment on the future of the News Blog again:

Going forward, the team will continue to grow and the goal remains the same: to provide our customers with carefully chosen, high-quality information about the latest and most meaningful AWS launches. The blog is in great hands and this team will continue to keep you informed even as the AWS pace of innovation continues to accelerate.

Since 2016, Jeff has been building the AWS News Blog as a team. Currently, we’re a group of 11 bloggers working in North America, South America, Asia, Europe, and Africa. We co-work with AWS product teams, testing new features firsthand on behalf of customers, and delivering key details in the News Blog the way Jeff has always done.

The Leadership Principles for AWS News Bloggers that Jeff shared on LinkedIn are a textbook for anyone writing for customers in tech companies. They’re the fundamentals that can help you understand and get started blogging quickly, and we’ll continue to stick to these principles with our team. This is why the AWS News Blog is different from other tech companies’ product news channels.

Voices from blog writers
You may be familiar with the names of News Blog writers, but you may not have had the chance to hear about them. Let us introduce ourselves!

Channy Yun (윤석찬)

I’m honored to continue Jeff’s legacy as a new lead blogger of the News Blog team; he is my role model. When I joined AWS in 2014, the first thing I did was to create the AWS Korea Blog and I started translating Jeff’s blog posts into the Korean language. During the journey, I learned how to write accurate, honest, and powerful guides to help customers get started with new AWS products and features.

Danilo Poccia

Since my first News Blog post in 2018, I have learned so much by being part of this team. Working with product managers and service teams is always an amazing experience. I am interested in serverless, event-driven architectures, and AI/ML. It’s incredible how technologies like generative AI are becoming part of software development implicitly (through AI-enabled development tools) and explicitly (by using models in code).

Sébastien Stormacq

I’m fortunate to have been a part of this team since 2019. When I don’t write posts, I produce episodes of the AWS Developers Podcast and le podcast AWS en français. I also work with the teams for Amazon EC2 Mac, AWS SDK for Swift, and the CodeBuild and CodeArtifact teams trying to make the AWS Cloud easier to use for Apple developers. My pet project is the Swift Runtime for AWS Lambda.

Veliswa Boya

The Amazon Leadership Principles (LPs) guide all that we do here at AWS, including the work we do as authors of the News Blog. As a developer advocate, I’ve taken the guidance of the LPs and used it to guide members of the AWS community who are looking to create technical content, especially those new in their technical content creation journey.

Donnie Prakoso

Just like brewing coffee, being a blog author has been a mix of fun, challenge, and reward. I’ve been particularly fortunate to observe how customer obsession is built into AWS teams. I’ve seen how they work backwards, transforming your feedback into services or features. I genuinely hope that you enjoy reading our articles and look forward to the next chapter of the News Blog team.

Esra Kayabali

As an author, I’m committed to delivering timely information about the latest AWS innovations and launches to our global audience of builders, developers, and technology enthusiasts. I understand the importance of providing clear, accurate, and actionable content that helps you use AWS services effectively. Happy reading everyone!

Matheus Guimaraes

My specialties are .NET development and microservices, but I’ve always been a jack-of-all-trades and writing for this blog helps me to keep my knife sharp across all corners of modern technology, while also helping others do the same. Thousands of people read the AWS News Blog and use it as a go-to source to keep up with what’s new and to help them make decisions, so I know that what we are doing is meaningful work with huge impact.

Prasad Rao

Through my blogs, I strive to highlight not just the “what” of new services, but also the “why” and “how” they can transform businesses and user experiences. As a solutions architect specializing in Microsoft Workloads on AWS, I help customers migrate and modernize their workloads and build scalable architecture on AWS. I also mentor diverse people to excel in their cloud careers.

Elizabeth Fuentes

Every time I start writing a new blog, I feel honored to be part of this team, to be able to experiment with something new before it’s released, and to be able to share my experience with the reader. This team is made up of specialists of all levels and from multiple countries and together, we are a multicultural and multi-specialty team. Thank you, reader, for being here.

Betty Zheng (郑予彬)

Joining the News Blog team has transformed how I communicate about technology. With an ever-curious mindset, I approach each new announcement aiming to make innovative services accessible and engaging. By bringing my unique and diverse perspective to technical content, I strive to help developers truly enjoy exploring our latest technologies.

Micah Walter

As a senior solutions architect, I support enterprise customers in the New York City region and beyond. I advise executives, engineers, and architects at every step along their journey to the cloud, with a deep focus on sustainability and practical design.

I also want to give credit to our behind-the-scenes editor-in-chief, Jane Watson, and program manager, Jane Scolieri, who play an essential role in helping us get product launch news to you as soon as it happens, including the 60 launches we announced in one week at re:Invent 2024!

Share your feedback
At AWS, we are customer obsessed. We’re always focused on improving and providing a better customer experience, and we need your feedback to do so. Take our survey to share insights about your experience with the AWS News Blog and suggestion for how we can serve you even better.

This survey is hosted by an external company. AWS handles your information as described in the AWS Privacy Notice. AWS will own the data gathered via this survey and will not share the information collected with survey respondents.

Channy

Dell Precision 3280 Compact Review A Neat Compact Workstation

Post Syndicated from Patrick Kennedy original https://www.servethehome.com/dell-precision-3280-compact-review-a-neat-compact-intel-nvidia-workstation/

In our Dell Precision 3280 Compact review, we see how we got 128GB of memory, a 20GB NVIDIA GPU, RAID 0 SSDs, and 24 cores into a small PC

The post Dell Precision 3280 Compact Review A Neat Compact Workstation appeared first on ServeTheHome.

Automating Sender ID Configuration for SMS with AWS End User Messaging APIs

Post Syndicated from Tyler Holmes original https://aws.amazon.com/blogs/messaging-and-targeting/automating-sender-id-configuration-for-sms-with-aws-end-user-messaging-apis/

Global SMS messaging with consistent Sender ID branding requires configuring the same Sender ID across multiple countries, which is a time-consuming process for businesses operating internationally. In this post, we’ll show you how to automate the configuration of Sender IDs for countries that do not have registration requirements using the AWS End User Messaging v2 API.

The Challenge of Multi-Country Sender ID Configuration

When sending SMS messages internationally, if you are using Sender ID, you want your brand to be consistently recognized. This means configuring the same Sender ID in each country you send to. However there are several challenges related to this:

  • Each country must be done manually, one at a time, if using the AWS Console
  • If you have multiple environments for testing the process must be repeated for each Account/Region
  • If you are moving account/regions you have to reconfigure each country in the new Account/Region
  • Manual configuration can be error prone
  • Errors can be detrimental to a brand

The Solution: AWS Lambda Automation

This solution can be applied to any country that supports Sender ID configurations and does not require registration. You can view a comprehensive list of these eligible countries here.

Below is an AWS Lambda function that streamlines this process by handling bulk configuration requests. The function solves the challenges in handling multiple country configurations in a single automated workflow. Here’s the complete code:

import boto3
import uuid
import json
import time
from typing import Dict, Any, List

def validate_input(sender_id: str, countries: List[str]) -> bool:
    if not 1 <= len(sender_id) <= 11:
        raise ValueError("Sender ID must be between 1 and 11 characters")
    
    if not sender_id.replace('_', '').replace('-', '').isalnum():
        raise ValueError("Sender ID can only contain alphanumeric characters, underscore, and hyphen")
    
    if not countries:
        raise ValueError("At least one country code must be provided")
    
    return True

def request_sender_id(client, sender_id: str, countries: List[str], message_types: List[str] = None, tags: List[Dict] = None) -> List[Dict]:
    if message_types is None:
        message_types = ["TRANSACTIONAL", "PROMOTIONAL"]
    
    results = []
    
    for i, country in enumerate(countries):
        if i > 0:
            time.sleep(1)  # Rate limiting: 1 request per second
            
        try:
            print(f"Processing country: {country} ({i+1}/{len(countries)})")
            request_params = {
                'ClientToken': str(uuid.uuid4()),
                'SenderId': sender_id,
                'IsoCountryCode': country.upper(),
                'MessageTypes': message_types,
                'DeletionProtectionEnabled':True
            }
            
            if tags:
                request_params['Tags'] = tags
                
            response = client.request_sender_id(**request_params)
            
            results.append({
                'Country': country,
                'Status': 'Success',
                'SenderIdArn': response.get('SenderIdArn'),
                'MonthlyLeasingPrice': response.get('MonthlyLeasingPrice')
            })
            
        except Exception as e:
            results.append({
                'Country': country,
                'Status': 'Failed',
                'Error': str(e)
            })
            
        print(f"Completed {country}: {'Success' if results[-1]['Status'] == 'Success' else 'Failed'}")
    
    return results

def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
    try:
        # Extract parameters from event
        sender_id = event['sender_id']
        countries = [c.strip().upper() for c in event['countries'] if c.strip()]
        tags = event.get('tags')  # Optional
        message_types = event.get('message_types', ["TRANSACTIONAL", "PROMOTIONAL"])  # Optional
        
        # Validate input
        validate_input(sender_id, countries)
        
        # Initialize the AWS SMS Voice v2 client
        client = boto3.client('pinpoint-sms-voice-v2')
        
        # Process the request
        results = request_sender_id(
            client=client,
            sender_id=sender_id,
            countries=countries,
            message_types=message_types,
            tags=tags
        )
        
        # Calculate summary
        successful = sum(1 for r in results if r['Status'] == 'Success')
        
        return {
            'statusCode': 200,
            'body': {
                'results': results,
                'summary': {
                    'total': len(countries),
                    'successful': successful,
                    'failed': len(countries) - successful
                }
            }
        }
        
    except Exception as e:
        return {
            'statusCode': 500,
            'body': {
                'error': str(e)
            }
        }

How the Lambda Function Works to Configure Sender IDs

The Lambda function automates the Sender ID configuration process through these key steps:

  • Input Validation: Ensures the Sender ID meets format requirements (1-11 alphanumeric characters, with optional underscores or hyphens).
  • Bulk Registration: Processes each country sequentially with built-in rate limiting (1 request per second) to prevent API throttling.
  • Logging: Returns the full ARN of each successfully configured Sender ID
  • Flexible Configuration Settings:
    • Supports multiple message types (transactional, promotional, or both)
    • Enables resource tagging for organizational and cost tracking
    • Provides deletion protection to prevent accidental removal
  • Cost Transparency: Displays monthly leasing price for each successful country configuration
  • Error Handling: Individual country failures don’t halt the entire process, allowing partial success if a single country were to fail for some reason.

Using the Lambda Function

To use this function, create a Lambda with the code above and configure an event. The tags are optional and we have provided an example below:
NOTE: Depending on the number of countries you are attempting to register at a time, you may need to increase the 3 second default Lambda timeout. For reference, in our testing, we were able to do all Sender IDs(160) in less than 3 minutes.

Test Event Example

{
    "sender_id": "YourBrand",
    "countries": ["GB", "DE", "FR"],
    "tags": [
        {
            "Key": "Environment",
            "Value": "Production"
        },
        {
            "Key": "Department",
            "Value": "Marketing"
        }
    ]
}

IAM Permissions

Your Lambda will need these minimum AWS Identity and Access Management (IAM) permissions, scale back the resource if necessary:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sms-voice:RequestSenderId",
                "sms-voice:TagResource"
            ],
            "Resource": "arn:aws:sms-voice:*:**ACCOUNT#**:sender-id/*"
        }
    ]
}

The Trust Policy required for Lambda to assume the role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "lambda.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

Results Example

The Lambda will return results for each country, including configuration status and monthly costs, if any. Below you will see an example of 3 countries being configured:


{
  "statusCode": 200,
  "body": {
    "results": [
      {
        "Country": "GB",
        "Status": "Success",
        "SenderIdArn": "arn:aws:sms-voice:us-west-2:**ACCOUNT#**:sender-id/LAMBDATEST2/GB",
        "MonthlyLeasingPrice": "0.00"
      },
      {
        "Country": "DE",
        "Status": "Success",
        "SenderIdArn": "arn:aws:sms-voice:us-west-2:**ACCOUNT#**:sender-id/LAMBDATEST2/DE",
        "MonthlyLeasingPrice": "0.00"
      },
      {
        "Country": "FR",
        "Status": "Success",
        "SenderIdArn": "arn:aws:sms-voice:us-west-2:**ACCOUNT#**:sender-id/LAMBDATEST2/FR",
        "MonthlyLeasingPrice": "0.00"
      }
    ],
    "summary": {
      "total": 3,
      "successful": 3,
      "failed": 0
    }
  }
}
Function Logs:
START RequestId: 81d2d144-9023-413d-b976-c87c79a82eae Version: $LATEST
Processing country: GB (1/3)
Completed GB: Success
Processing country: DE (2/3)
Completed DE: Success
Processing country: FR (3/3)
Completed FR: Success

After processing your Sender ID configurations, it’s crucial to verify them. You can do this via the AWS console or by using the DescribeSenderIds API. This API offers flexible retrieval options:

  • Specify individual Sender IDs for targeted information
    • Providing an invalid Sender ID will result in an error
  • Apply filters to narrow your results
  • Retrieve all Sender IDs associated with your AWS account by omitting both

Conclusion

Automating Sender ID configuration with the AWS End User Messaging v2 API and a Lambda function will dramatically reduce the time spent on manual configuration, ensure consistent branding across all supported and configured countries, and simplify a complex process. You’ll gain a scalable, reliable solution that allows you to deploy and manage your Sender IDs with confidence.

Additional resources:

AWS End User Messaging SMS documentation

SMS V2 API

[$] Slab allocator: sheaves and any-context allocations

Post Syndicated from corbet original https://lwn.net/Articles/1016001/

The kernel’s slab allocator is charged with providing small objects on
demand; its performance and reliability are crucial for the functioning of
the system as a whole. At the 2025 Linux Storage, Filesystem,
Memory-Management, and BPF Summit, two adjacent sessions in the
memory-management track dug into current work on the slab allocator. The
first focused on the new sheaves feature, while the second discussed a set
of allocation functions that are safe to call in any context.

Dave Täht RIP

Post Syndicated from corbet original https://lwn.net/Articles/1016109/

[Dave Täht]

From the LibreQoS site comes the sad
news
that Dave Täht has passed away. Among many other things, he bears
a lot of credit for our networks functioning as well as they do. “We’re
incredibly grateful to have Dave as our friend, mentor, and as someone who
continuously inspired us – showing us that we could do better for each
other in the world, and leverage technology to make that happen. He will be
dearly missed
“.

Searching through LWN’s archives will turn up many references to his work
fixing WiFi, improving queue management, tackling bufferbloat, and more. Farewell,
Dave, we hope the music is good wherever you are.

(Thanks to Jon Masters for the heads-up).

A New Approach to Managing Vulnerabilities is Required – Work Smarter not Harder with Rapid7 Remediation Hub

Post Syndicated from Peter Whibley original https://blog.rapid7.com/2025/04/01/a-new-approach-to-managing-vulnerabilities-is-required-work-smarter-not-harder-with-rapid7-remediation-hub/

A New Approach to Managing Vulnerabilities is Required - Work Smarter not Harder with Rapid7 Remediation Hub

The volume of common vulnerabilities and exposures (CVEs) identified has now reached a level that even the organization tasked with managing them can no longer keep up. The National Vulnerability Database (NVD) announced in February 2024 that it would no longer provide common vulnerability scoring system (CVSS) scores for all CVEs.

This decision was down to resource constraints and an inability to keep up with the volume of newly-disclosed vulnerabilities. The NVD has now shifted its focus to processing vulnerabilities more efficiently by relying on vendor-provided and third-party scores rather than scoring each CVE independently.

The Growing Vulnerability Challenge

In 2024, there were over 40,000 Common Vulnerabilities and Exposures (CVEs) published, which is a 38% increase from 2023. All of this is before organisations begin looking at other non-CVE vulnerabilities (configuration issues, outdated systems, elevated privileges etc) that can be just as important as vulnerabilities that do have a CVE. Even the NVD is saying that a new approach to vulnerability management is required.

The Limits of Traditional Risk-Based Vulnerability Management

A key component of Risk Based Vulnerability Management (RBVM) is prioritization. Prioritizing vulnerabilities based on their calculated risk scores, then focusing on addressing or remediating the highest-risk vulnerabilities first.

However, in the high volume vulnerability landscape we face today, security teams are often faced with multiple vulnerabilities with similar high priority risk scores? What do you tackle first?

Many organizations, including Rapid7, are addressing this issue by adding more context when calculating risk score including the use of AI. But still the challenge remains, what do you prioritize first if vulnerabilities have the same risk score?

Introducing Remediation Hub: A Solution First Approach

That’s where Remediation Hub can help. Rapid7’s Remediation Hub takes a remediation-based view rather than an individual CVE based view of vulnerability management. It shows security teams the volume of vulnerabilities that will be resolved by carrying out a recommended remediation. This allows security teams to carry out bulk vulnerability removal by selecting a recommended remediation.

Recommended remediations are still prioritized based on risk, specifically a group risk score that considers:

  • The number of vulnerabilities that will be resolved.
  • The criticality of the vulnerabilities.
  • The number of assets impacted and their exploitability.

Rather than simply focusing on remediating a single CVE with the highest risk, security teams are instead guided to focus their work where it will be most effective, deliver the biggest impact on overall risk and thus drive improvement to employee productivity.

Unifying Security Operations with Exposure Command

Remediation Hub is a foundational component of the Exposure Command cybersecurity platform. Within the Exposure Command platform, Remediation Hub acts as a centralised location for all remediation efforts and is tightly integrated with the various platform components.

Via integration between Surface Command, Rapid7’s attack surface management (ASM) platform, and Remediation Hub, users can now see recommended remediations when viewing an individual asset or the asset inventory. Within the Remediation Hub itself users can drill down to obtain information and more context on the assets impacted by carrying out a specific remediation.

Security teams can see concrete vulnerability evidence or proof before assigning fixes to remediation teams and can export a prioritized list of solutions for streamlined remediation. This tight integration improves employee productivity and accelerates mean-time-to-remediate (MTTR), eliminating the need to jump between tools to obtain more context.

How the Rapid7 Remediation Hub Works

Remediation Hub ingests vulnerability data from both customer cloud and on-prem landscapes. Rather than presenting security professionals with a long list of vulnerabilities identified across their attack surface, Remediation Hub  provides users with a list of recommended remediations that are prioritized based on an algorithm-driven risk score. Security employees are thus guided to where they can have the most impact in reducing overall risk.

Working Smarter in Vulnerability Management

Due to the extent, complexity and dynamic nature of today’s IT networks, it’s clear that a new approach to managing vulnerabilities is required. The focus for cybersecurity platforms like Rapid7 Exposure Command is no longer on just identifying and prioritizing vulnerabilities but on what you do with them. We need to help security teams cut through the noise, to intelligently manage vulnerabilities and focus on where they can be most effective and productive.

Security teams carrying out remediation must start working smarter not harder.

For more information on Remediation Hub:

Empowering India’s digital future: Our computing curriculum’s impact

Post Syndicated from Ben Durbin original https://www.raspberrypi.org/blog/empowering-indias-digital-future-our-computing-curriculums-impact/

The Raspberry Pi Foundation has been working in India since 2018 to enable young people to realise their potential through the power of computing and digital technologies. 

We’ve supported Code Clubs, partnered with government organisations, and designed and delivered a complete computing curriculum for students in grades 6 to 12 and at the undergraduate level. Our curriculum is tailored to the Indian context, and we provide extensive support to help teachers deliver it effectively.

Three female students at the Coding Academy in Telangana.

In another recent blog, we shared in detail how we’ve created an impactful curriculum for India. We’re now excited to share our new report evaluating how our curriculum is being taught in Telangana and Odisha. This report demonstrates the impact we’ve had so far, highlighting our successes and the key lessons we have learnt.

Key findings from the evaluation

Our evaluations of how the curriculum is being taught show that teachers are well-equipped to deliver the curriculum and provide high-quality and accessible learning experiences that develop students’ computing knowledge and skills.

A group of students in a classroom.

In Telangana, we partnered with the Telangana Social Welfare Residential Educational Institutions Society (TGSWREIS) to introduce our curriculum at the Coding Academy School and Coding Academy College. Our report found that all school and college teachers we trained agreed they felt confident teaching students using the resources provided. Students were very positive about the classes, and their assessment scores demonstrated strong learning outcomes: 77% of school students and 70% of college students achieved at least 60% of available marks.

In Odisha, we worked with Learning Links Foundation and Quest Alliance, in partnership with Panchasakha Sikhya Setu (PSS) Abhiyan, to deliver the IT and Coding Curriculum (Kaushali) to students in grades 9 and 10. Our findings were also very positive:

  • 87% of teacher respondents agreed that the curriculum resources were high quality and useful for their teaching
  • 91% felt more confident about teaching IT and coding due to the curriculum resources
  • 93% of teachers agreed that the training helped them understand the curriculum’s structure, content, and objectives
  • 89% felt confident in teaching the curriculum after the training
  • Teachers also reported a positive impact on their students, with almost all agreeing that it improved students’ coding skills, digital literacy, and understanding of responsible digital citizenship

The report also highlights how students better understood how computing and coding are used in the world and developed an increased interest in pursuing careers in these fields.

Key factors for effective implementation

Our evaluations show the importance of several factors when launching a computing curriculum:

  • Aligning content with students’ experience and interests: Content should be tailored to students’ existing knowledge, culturally relevant, and follow industry standards to prepare them for employment
  • Providing extensive support to teachers: This includes careful selection and training of master teachers, comprehensive training for teachers that considers their knowledge and experience, and ongoing support through webinars, calls, and classroom observations
  • Ensuring sufficient quantity and quality of infrastructure: Adequate equipment and internet access are crucial for effective teaching and learning

We are committed to always improving our approach to ensure that all young people in India have the opportunity to learn about computing.

Join us in shaping the future

You can read our new report here. If you are interested in partnering with us or want to learn more about our mission, please contact [email protected].

The post Empowering India’s digital future: Our computing curriculum’s impact appeared first on Raspberry Pi Foundation.

The collective thoughts of the interwebz