¿Cómo escribir un script que edite el archivo de brillo en / sys / class / backlight / ideapad /?

Dec 19 2020

Estoy usando i3 wm y tengo mi archivo de brillo en formato /sys/class/backlight/ideapad/brightness.

╰─$ ls -la /sys/class/backlight/ideapad/

-rw-r--r-- 1 root root 4096 Dec 18 16:55 brightness

Cuando quiero cambiar el brillo (diga a 4) lo hago:

sudo sh -c "echo 4 > /sys/class/backlight/ideapad/brightness"

Me gustaría escribir una secuencia de comandos que aumentaría o disminuiría el brillo en 1 y luego vincular esa secuencia de comandos a alguna combinación de teclas en el archivo de configuración i3 wm ( CTRL+F1por ejemplo) para poder controlar el brillo presionando teclas en lugar de editar el archivo de brillo manualmente cada vez que quiera cambiar el brillo.

Dado que esto requiere privilegios de root, no estoy seguro de cómo lograrlo. ¿Debo cambiar a mi usuario como propietario del brightnessarchivo o simplemente debo cambiar el grupo del archivo? ¿O de cualquier otra forma que se te ocurra?

Respuestas

1 Quasímodo Dec 19 2020 at 19:30

/syses un sistema de archivos virtual basado en RAM , por lo que cambiar el permiso de sus archivos no sobrevivirá a un reinicio.

Este programa en C es la solución que escribí hace algún tiempo y nunca me ha fallado. No requiere nada que no tenga un sistema Linux estándar.

#include <stdlib.h>
#include <stdio.h>
#define BUFSIZE 10

int main(int argc, char **argv) {
  FILE *fp;
  char scurr[BUFSIZE];
  long new, curr, incr, min = 10;

  /* An argument with an integer increment must be supplied */
  if (argc != 2 || (incr = strtol(argv[1], NULL, 10)) == 0) { return(1); }

  /* Retrieve the current brightness and increment it in the brightness file */
  if ((fp = fopen("/sys/class/backlight/ideapad/brightness", "r+")) 
      && fgets(scurr, BUFSIZE, fp)) {
    curr = strtol(scurr, NULL, 10);
    rewind(fp);
    new = curr + incr;
    if (new < min) { new = min; }
    fprintf(fp, "%ld\n", new);
    fclose(fp);
  } else { return(2); }

  return(0);
}

Compílelo ( br.ces el nombre del archivo, brel ejecutable), haga que root sea el propietario, active el bit setuid y coloque el ejecutable en algún lugar de su PATH( /usr/local/bin/es una opción típica).

cc br.c -o br
chown root br
chmod u+s  br
mv br /usr/local/bin/

Ahora, con solo ejecutarlo, se br -100reduce el brillo en 100.

Vea que también he establecido el brillo mínimo en min = 10. Eso es bastante bajo en mi máquina que apenas se nota que la pantalla está encendida. Modifique ese valor según sus necesidades. También para muchas personas, el componente de ruta será algo así como en intel-backlightlugar de ideapad.


Enfoque alternativo

Setuid otorga brderechos de root completos. Aunque esto no genera exploits en este programa en particular, si desea ser muy cauteloso y darle solo el conjunto de privilegios necesario, es decir, para omitir la verificación de permisos de archivos, sustituya las líneas chowny chmodanteriores por la capacidad adecuada.

setcap cap_dac_override+ep br
1 ArkadiuszDrabczyk Dec 19 2020 at 00:45

Cambiar la propiedad del grupo suele ser el camino a seguir, pero tenga en cuenta que tendrá que hacerlo cada vez que reinicie. Para hacer esto, cree automáticamente la regla udev como se describe en Arch wiki :

De forma predeterminada, solo root puede cambiar el brillo con este método. Para permitir que los usuarios del grupo de videos cambien el brillo, se puede usar una regla udev como la siguiente:

/etc/udev/rules.d/backlight.rules

ACTION=="add", SUBSYSTEM=="backlight", KERNEL=="acpi_video0", GROUP="video", MODE="0664"

Si no es miembro del videogrupo, agregue su usuario a él:

sudo gpasswd video -a $(whoami)

Tenga en cuenta que ha cerrado y vuelto a iniciar sesión para actualizar la información de membresía del grupo:

su -l $(whoami)

Compruebe si es miembro de un videogrupo con id, debería imprimir algo como:

$ id
uid=1000(ja) gid=100(users) groups=100(users),16(dialout),17(audio),18(video),83(plugdev),215(vboxusers),281(docker)

Por supuesto, puede usar cualquier grupo del que su usuario sea miembro en la regla udev, no necesariamente video.