From 545814f3792c9d7e5702cb6112ef949e2a1fd263 Mon Sep 17 00:00:00 2001 From: Mitchell Riedstra Date: Sat, 31 Dec 2022 20:00:08 -0500 Subject: Rewrite the backlight script into a setuid C program --- bin/.gitignore | 1 + bin/Makefile | 5 +- bin/backlight | 28 ---------- bin/backlight.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 29 deletions(-) delete mode 100755 bin/backlight create mode 100644 bin/backlight.c diff --git a/bin/.gitignore b/bin/.gitignore index b1a17ba..4711d71 100644 --- a/bin/.gitignore +++ b/bin/.gitignore @@ -1 +1,2 @@ zzz +backlight diff --git a/bin/Makefile b/bin/Makefile index c7e37e6..b0a8dd1 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -5,8 +5,11 @@ install-zzz: zzz install -D -o root -g root -m 755 zzz /sbin/ chmod 6755 /sbin/zzz +install-linux: backlight + install -D -o root -g root -m 755 backlight /sbin/ + chmod 6755 /sbin/backlight + linux: - install backlight $(HOME)/bin install wpa $(HOME)/bin install: diff --git a/bin/backlight b/bin/backlight deleted file mode 100755 index a0d6176..0000000 --- a/bin/backlight +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -set -e -set -x -# Note the trailing slash -base="/sys/class/backlight/amdgpu_bl0/" -# base="/sys/class/backlight/intel_backlight/" -# pinebook -# base="/sys/class/backlight/backlight/" -_backlight="${base}brightness" -_max="${base}max_brightness" -_max="$(awk '{print $1/100;}' < "$_max")" - -percent="$(echo "$1" | awk '{print int($1*'"$_max"');}')" - -if ! [ -w "$_backlight" ] ; then - sudo chgrp "$(id -g)" "$_backlight" - sudo chmod g+w "$_backlight" -fi - - -sh -c "echo \"$percent\" > $_backlight" - -## If you want to do this withotu a password: -# %wheel ALL=(ALL) NOPASSWD: /usr/bin/chgrp 1001 /sys/class/backlight/amdgpu_bl0/brightness -# %wheel ALL=(ALL) NOPASSWD: /usr/bin/chmod g+w /sys/class/backlight/amdgpu_bl0/brightness -# %wheel ALL=(ALL) NOPASSWD: /usr/bin/chgrp 1001 /sys/class/backlight/intel_backlight/brightness -# %wheel ALL=(ALL) NOPASSWD: /usr/bin/chmod g+w /sys/class/backlight/intel_backlight/brightness - diff --git a/bin/backlight.c b/bin/backlight.c new file mode 100644 index 0000000..5894cd8 --- /dev/null +++ b/bin/backlight.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +const char *backlight_f[] = { + "/sys/class/backlight/intel_backlight/", + "/sys/class/backlight/amdgpu_bl0/", +}; + +void +die(const char *msg) +{ + puts(msg); + exit(1); +} + +void +err(const char *msg) +{ + perror(msg); + exit(1); +} + +void* +ecalloc(size_t nmemb, size_t size) +{ + void *ret = calloc(nmemb, size); + if (!ret) + err("ecalloc"); + return ret; +} + +char* +appendStr(size_t len, const char *a, const char *b) +{ + char *buf = ecalloc(len, sizeof(char)); + int ret = snprintf(buf, len, "%s%s", a, b); + if (ret == -1 || ret > len) + err("snprintf"); + return buf; +} + +/* returns errno */ +int +maxBrightness(const char *prefix, long *max) +{ + int e; + char *buf = appendStr(256, prefix, "/max_brightness"); + + int fd = open(buf, O_RDONLY); + if (fd == -1) { + e = errno; + free(buf); + return e; + } + + memset(buf, '\0', 256); + + int b = read(fd, buf, 256); + if (b==-1) { + e = errno; + free(buf); + close(fd); + return e; + } + + for (int i=0; i<256 ; i++) { + if (buf[i] == '\n') { + buf[i] = '\0'; + break; + } + } + + long n = strtol(buf, NULL, 10); + if (n == LONG_MIN || n == LONG_MAX || n == 0) + err("strtol"); + + free(buf); + buf = NULL; + close(fd); + *max = n; + + return 0; +} + +int +setBacklight(const char *prefix, int percent) +{ + char *fn = appendStr(256, prefix, "/brightness"); + + int fd = open(fn, O_WRONLY); + if (fd == -1) { + free(fn); + return -1; + } + + int n = dprintf(fd, "%d\n", percent); + if (n == -1) { + close(fd); + free(fn); + return -1; + } + + close(fd); + free(fn); + fn = NULL; +} + +int +main(int argc, char **argv) +{ + uid_t uid = getuid(); + gid_t gid = getgid(); + uid_t euid = geteuid(); + char **a = argv+1; + pid_t pid; + int ret; + + if (euid != 0) + die("Program must be run as root/setuid"); + + if (!*a) + die("Brightness percentage must be supplied"); + + + long percent = strtol(*a, NULL, 10); + if (percent <= LONG_MIN || percent >= LONG_MAX) + err("invalid percent"); + if (percent < 0 || percent > 100) + die("percent must be between 0 and 100"); + + + for (int i=0; i < sizeof(backlight_f)/sizeof(backlight_f[0]); i++) { + int ret; + long max = 0; + ret = maxBrightness(backlight_f[i], &max); + if (ret != 0) { + const char *msg = strerror(ret); + continue; + } + + float p = (double)max*((double)percent/100.0); + + ret = setBacklight(backlight_f[i], (int)p); + if (ret != 0) { + perror("setBacklight"); + } + } + + + + +} -- cgit v1.2.3