mirror of
https://github.com/X11Libre/xf86-video-intel.git
synced 2026-03-24 01:24:12 +00:00
Adam Sampson spotted that
"It's possible (but not very sensible) to exec a program with an empty
argument list, so argv[0] is not necessarily a valid pointer. For
example:
$ cat exec0.c
int main(int argc, char *argv[]) {
char *empty[1] = { NULL };
execvp(argv[1], empty);
perror("execvp");
return 1;
}
$ ./exec0 /usr/libexec/xf86-video-intel-backlight-helper
Usage: (null) <iface>
"
He sensibly suggested that we hardcode the program name to avoid the
NULL dereference. Being the paranoid type, we should also be careful not
to write to any file descriptors outside of our control (i.e. stderr),
so disable the messages unless we are debugging.
Reported-by: Adam Sampson
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
59 lines
1.2 KiB
C
59 lines
1.2 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
#define DBG 0
|
|
|
|
#if defined(__GNUC__) && (__GNUC__ > 3)
|
|
__attribute__((format(printf, 1, 2), noreturn))
|
|
#endif
|
|
static void die(const char *format, ...)
|
|
{
|
|
if (DBG) {
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
|
vfprintf(stderr, format, args);
|
|
va_end(args);
|
|
}
|
|
|
|
exit(1);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
struct stat st;
|
|
char buf[1024];
|
|
int len, fd;
|
|
|
|
if (argc != 2)
|
|
die("Usage: xf86-video-intel-backlight-helper <iface>\n");
|
|
|
|
if (strchr(argv[1], '/') != NULL)
|
|
die("Invalid interface '%s': contains '/'\n", argv[1]);
|
|
|
|
if (snprintf(buf, sizeof(buf),
|
|
"/sys/class/backlight/%s/brightness",
|
|
argv[1]) >= sizeof(buf))
|
|
die("Invalid interface '%s': name too long\n", argv[1]);
|
|
|
|
fd = open(buf, O_RDWR);
|
|
if (fd < 0 || fstat(fd, &st) || major(st.st_dev))
|
|
die("Invalid interface '%s': unknown backlight file\n", argv[1]);
|
|
|
|
while (fgets(buf, sizeof(buf), stdin)) {
|
|
len = strlen(buf);
|
|
if (write(fd, buf, len) != len)
|
|
die("Failed to update backlight interface '%s': errno=%d\n", argv[1], errno);
|
|
}
|
|
|
|
return 0;
|
|
}
|