Hacker News new | ask | show | jobs
Directly access your physical memory (dev/mem) (bakhi.github.io)
58 points by blueblueue 1249 days ago
9 comments

Not super related but a pleasantly surprising linux /dev trick I discovered yesterday was piping “hello” to /dev/udp/<ip>/<port> in order to check connectivity between two machines (the other was listening using nc)
To be pedantic, that’s provided by bash, not devfs. You wouldn’t be able to do it like this from e.g. a C program.
You mean that bash interprets the path and creates the socket itself?
Yes, bash does that. It's a bash feature:

https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash....

> Bash handles several filenames specially when they are used in redirections, as described in the following table. If the operating system on which Bash is running provides these special files, bash will use them; otherwise it will emulate them internally with the behavior described below.

> ...

> Bash attempts to open the corresponding [...] socket.

I think this was a design mistake. If they wanted to come up with a new syntax for sending UDP packets, fine.

If they persuaded the kernel devs to make some devfs way that those were real files, using the unix filesystem API, also fine.

But making something that looks like a real thing in the filesystem, but isn't usable by other programs that use the filesystem... Thats not right.

Even more fun is that if you create /dev/udp/127.0.0.1 (and chmod a+rwx), it won't create the file 53 if you "echo hello > /dev/udp/127.0.0.1/53". Instead it sends a UDP packet to your DNS server.

If you create a symlink to a path like /dev/udp/127.0.0.1/53 and redirect output to the symlink, a packet is not sent; the file is written as normal.

I'm guessing nobody has ever actually had a problem with this, so it's not actually a bad design choice, but I personally wouldn't have written that code. Leaky abstraction.

I dunno, if you “echo foo > /dev/null” then “cat /dev/null” you won’t get foo back. Plenty of assumptions about filesystem behaviour don’t work in all cases.

That being said, I’d prefer if the symlink actually worked and sent the packet.

That’s probably because bash is only looking for those types of paths in a redirection context. But if you try to use regular file utilities those paths don’t have any special meaning so they just work as normal.
Yes.
One can do something similar with gawk.

https://www.gnu.org/software/gawk/manual/gawkinet/gawkinet.h...

For example, one could run gawk under dash (scripting shell) instead of bash (interactive shell), for instance in a script.

This is pretty tangential but seeing this reminds me of the days when the puredyne distro used to pipe /dev/mem to /dev/dsp as a noisy startup chime.
If you had lots of ram this may have taken a while. In grad school we piped vmlinux and other files to /dev/dsp as a crude acoustic "tripwire" to "listen" to the system configuration.
I think we need to examine the definition of "pipe" in a POSIX context here. Pipelines feed the output of one program into the input of another one. You don't "pipe" files, you copy them.
I remember piping /dev/mouse (or whatever) to /dev/dsp to make noises when the mouse moved. Good times.
Talk about a memory leak.
I did that for some pics too, kinda funky to have actual memory map
The 'devmem' command is pretty neat when doing embedded systems, allowing you to write entire device drivers in bash!
That's a horrible idea. You should use javascript instead.
if you aren't using Lisp, then are you even a real driver developer?
I've done this. It was fun. PiFM was developed this way.
Make a game of it: How many random bytes can you write (to random locations) before (your program | the entire system) goes badly awry or unresponsive?
Think you just described core war. https://en.wikipedia.org/wiki/Core_War
Lol. Back in TurboC days I wrote my first “random” number generator by reading off memory. Win 98 I think
Take that, memory-safe programming languages!
Drawing to the vga frame buffer back in dos used to be as simple as setting a pointer to 0xA0000 in your c(++) program and writing to it. Fond memories!
This is also handy for directly accessing memory that's been mapped in from peripherals and special-purpose processors. Though it might not always work because of clock gating.
I'm surprised access through /dev/mem happens below the caching layer. I wouldn't have even thought of that possibility. Any idea why that is?
A very common usage for /dev/mem is to access a device through memory mapped IO from user space.

Cacheable accesses would break that use case.

If my memory serves me correctly you can control the mapped caching attributes using file flags, like O_SYNC, etc. Might also be architecture dependent. If you want to manipulate a memory-mapped device then you don't want caching, but if you want to see memory the same way a typical application does, then you want to keep the caching attributes in your mapping. It's a low-level tool, so there is no right or wrong really.
...it's memory. Where would you cache memory access, in other memory ?

CPU got cache for caching memory

Exactly - the article says "the memory might be cached by the CPU which possibly incurs cache coherence problem".

I would expect the memory access to happen through the CPU and its cache, avoiding such problems.

Isn't this a security risk?
- `/dev/mem` should only be accessible by root or whoever you set the permissions to (don't `chmod 777 /dev/mem`).

- root can install device drivers which have full executable run of the system anyway and do anything you can do with this device; this is also true on Windows.

- read about CONFIG_STRICT_DEVMEM - https://man7.org/linux/man-pages/man4/mem.4.html#:~:text=Sin....

- wait until you hear about `/dev/kmem`.

- it's possible to build a Linux kernel without `/dev/mem` support and also without loadable module support (I think), so if your threat model indicates this needs to be addressed it is possible.

`CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY=y` or similar may also be of interest, see `man kernel_lockdown`.
>root can install device drivers which have full executable run of the system anyway and do anything you can do with this device; this is also true on Windows.

Oddly enough, no. Or atleast last time I tried on Ubuntu I had to disable secure boot. Seemed like an easier way than to sign the build files

Secure Boot can be configured to also trust user keys. Ubuntu's installer does it automatically if you choose to install it with third-party drivers (like Nvidia). Those user keys are then available to root to sign any DKMS kernel modules.
It would be a fun exercise/YouTube video/class… you are an unprivileged user, /dev/mem is 777, go forth and prosper.