Skip to content

Instantly share code, notes, and snippets.

@Mufanc
Created July 1, 2023 07:44
Show Gist options
  • Save Mufanc/7b0d7bfdcf1bc31534dc7089f7a9bf28 to your computer and use it in GitHub Desktop.
Save Mufanc/7b0d7bfdcf1bc31534dc7089f7a9bf28 to your computer and use it in GitHub Desktop.
#include <cstdlib>
#include <iostream>
#include <sys/inotify.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/unistd.h>
#define TMP_FILE "/tmp/fake.brightness"
#define HIJACK_FILE "/sys/class/backlight/intel_backlight/brightness"
#define CHECK_ERR(func, ...) ({ \
auto result = func(__VA_ARGS__); \
if (result == -1) { \
std::perror(#func); \
std::exit(EXIT_FAILURE); \
} \
result; \
})
#define PRINT_LOG(pattern, ...) printf(("[*] " pattern "\n"), ##__VA_ARGS__)
int open_overlay() {
int fd;
if (access(TMP_FILE, F_OK) == 0) {
CHECK_ERR(chown, TMP_FILE, 0, 0);
CHECK_ERR(chmod, TMP_FILE, 0644);
fd = CHECK_ERR(open, TMP_FILE, O_RDONLY);
} else {
fd = CHECK_ERR(open, TMP_FILE, O_CREAT | O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
}
return fd;
}
int init_inotify() {
int inotify_fd = CHECK_ERR(inotify_init);
CHECK_ERR(inotify_add_watch, inotify_fd, TMP_FILE, IN_CLOSE_WRITE);
return inotify_fd;
}
int mount_overlay() {
struct stat buf_overlay { }, buf_hijack { };
CHECK_ERR(stat, TMP_FILE, &buf_overlay);
CHECK_ERR(stat, HIJACK_FILE, &buf_hijack);
if (buf_overlay.st_dev == buf_hijack.st_dev && buf_overlay.st_ino == buf_hijack.st_ino) {
PRINT_LOG("brightness hijack detected, umount old file first!");
CHECK_ERR(umount, HIJACK_FILE);
}
int original_fd = open(HIJACK_FILE, O_WRONLY);
CHECK_ERR(mount, TMP_FILE, HIJACK_FILE, "none", MS_BIND, nullptr);
PRINT_LOG("bind mount: " TMP_FILE " -> " HIJACK_FILE);
return original_fd;
}
int main() {
if (geteuid() != 0) {
PRINT_LOG("Please run as root!\n");
return EXIT_FAILURE;
}
PRINT_LOG("current pid: %d", getpid());
const int page_size = getpagesize();
int overlay_fd = open_overlay();
int inotify_fd = init_inotify();
int original_fd = mount_overlay();
void *addr = mmap(nullptr, page_size, PROT_READ, MAP_SHARED, overlay_fd, 0);
close(overlay_fd);
char buffer[4096] __attribute__((aligned(__alignof__(struct inotify_event))));
for (;;) {
ssize_t count = read(inotify_fd, buffer, sizeof(buffer));
if (count == 0) {
perror("inotify");
break;
}
const inotify_event *event;
for (char *ptr = buffer; ptr < buffer + count; ptr += sizeof(inotify_event) + event->len) {
event = reinterpret_cast<const inotify_event *>(ptr);
long level = std::strtol(static_cast<const char *>(addr), nullptr, 10);
printf("brightness level: %ld\r", level);
fflush(stdout);
CHECK_ERR(lseek, original_fd, 0, SEEK_SET);
CHECK_ERR(write, original_fd, addr, page_size);
}
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment