about summary refs log tree commit diff
path: root/pkgs/misc/beep
diff options
context:
space:
mode:
authorPeter Hoeg <peter@hoeg.com>2018-04-19 16:10:57 +0800
committerPeter Hoeg <peter@hoeg.com>2018-04-19 16:11:49 +0800
commit12ce0db1bffb048fbf81a852aed7240aedc31757 (patch)
tree09ed0e13fde5da2ca6b1192a3fdec077d01d5fc4 /pkgs/misc/beep
parente6c135486dd5fae6aabdf7155d200e45aef68262 (diff)
beep: fix for CVE-2018-0492
Diffstat (limited to 'pkgs/misc/beep')
-rw-r--r--pkgs/misc/beep/cve-2018-0492.patch106
-rw-r--r--pkgs/misc/beep/default.nix28
2 files changed, 124 insertions, 10 deletions
diff --git a/pkgs/misc/beep/cve-2018-0492.patch b/pkgs/misc/beep/cve-2018-0492.patch
new file mode 100644
index 0000000000000..533fc6c15578c
--- /dev/null
+++ b/pkgs/misc/beep/cve-2018-0492.patch
@@ -0,0 +1,106 @@
+diff --git a/beep.c b/beep.c
+index 7da2e70..4323d31 100644
+--- a/beep.c
++++ b/beep.c
+@@ -109,6 +109,7 @@ void do_beep(int freq) {
+      /* BEEP_TYPE_EVDEV */
+      struct input_event e;
+
++     memset(&e, 0, sizeof(e));
+      e.type = EV_SND;
+      e.code = SND_TONE;
+      e.value = freq;
+@@ -124,10 +125,6 @@ void do_beep(int freq) {
+ /* If we get interrupted, it would be nice to not leave the speaker beeping in
+    perpetuity. */
+ void handle_signal(int signum) {
+-
+-  if(console_device)
+-    free(console_device);
+-
+   switch(signum) {
+   case SIGINT:
+   case SIGTERM:
+@@ -257,7 +254,7 @@ void parse_command_line(int argc, char **argv, beep_parms_t *result) {
+       result->verbose = 1;
+       break;
+     case 'e' : /* also --device */
+-      console_device = strdup(optarg);
++      console_device = optarg;
+       break;
+     case 'h' : /* notice that this is also --help */
+     default :
+@@ -276,26 +273,6 @@ void play_beep(beep_parms_t parms) {
+	"%d delay after) @ %.2f Hz\n",
+	parms.reps, parms.length, parms.delay, parms.end_delay, parms.freq);
+
+-  /* try to snag the console */
+-  if(console_device)
+-    console_fd = open(console_device, O_WRONLY);
+-  else
+-    if((console_fd = open("/dev/tty0", O_WRONLY)) == -1)
+-      console_fd = open("/dev/vc/0", O_WRONLY);
+-
+-  if(console_fd == -1) {
+-    fprintf(stderr, "Could not open %s for writing\n",
+-      console_device != NULL ? console_device : "/dev/tty0 or /dev/vc/0");
+-    printf("\a");  /* Output the only beep we can, in an effort to fall back on usefulness */
+-    perror("open");
+-    exit(1);
+-  }
+-
+-  if (ioctl(console_fd, EVIOCGSND(0)) != -1)
+-    console_type = BEEP_TYPE_EVDEV;
+-  else
+-    console_type = BEEP_TYPE_CONSOLE;
+-
+   /* Beep */
+   for (i = 0; i < parms.reps; i++) {                    /* start beep */
+     do_beep(parms.freq);
+@@ -305,8 +282,6 @@ void play_beep(beep_parms_t parms) {
+     if(parms.end_delay || (i+1 < parms.reps))
+        usleep(1000*parms.delay);                        /* wait...    */
+   }                                                     /* repeat.    */
+-
+-  close(console_fd);
+ }
+
+
+@@ -328,6 +303,26 @@ int main(int argc, char **argv) {
+   signal(SIGTERM, handle_signal);
+   parse_command_line(argc, argv, parms);
+
++  /* try to snag the console */
++  if(console_device)
++    console_fd = open(console_device, O_WRONLY);
++  else
++    if((console_fd = open("/dev/tty0", O_WRONLY)) == -1)
++      console_fd = open("/dev/vc/0", O_WRONLY);
++
++  if(console_fd == -1) {
++    fprintf(stderr, "Could not open %s for writing\n",
++      console_device != NULL ? console_device : "/dev/tty0 or /dev/vc/0");
++    printf("\a");  /* Output the only beep we can, in an effort to fall back on usefulness */
++    perror("open");
++    exit(1);
++  }
++
++  if (ioctl(console_fd, EVIOCGSND(0)) != -1)
++    console_type = BEEP_TYPE_EVDEV;
++  else
++    console_type = BEEP_TYPE_CONSOLE;
++
+   /* this outermost while loop handles the possibility that -n/--new has been
+      used, i.e. that we have multiple beeps specified. Each iteration will
+      play, then free() one parms instance. */
+@@ -365,8 +360,8 @@ int main(int argc, char **argv) {
+     parms = next;
+   }
+
+-  if(console_device)
+-    free(console_device);
++  close(console_fd);
++  console_fd = -1;
+
+   return EXIT_SUCCESS;
+ }
diff --git a/pkgs/misc/beep/default.nix b/pkgs/misc/beep/default.nix
index ce097bd5f2312..762b8d65a8419 100644
--- a/pkgs/misc/beep/default.nix
+++ b/pkgs/misc/beep/default.nix
@@ -1,25 +1,33 @@
-{ stdenv, fetchurl }:
+{ stdenv, fetchFromGitHub }:
 
 # this package is working only as root
 # in order to work as a non privileged user you would need to suid the bin
 
 stdenv.mkDerivation {
   name = "beep-1.3";
-  src = fetchurl {
-    url = http://www.johnath.com/beep/beep-1.3.tar.gz;
-    sha256 = "0bgch6jq5cahakk3kbr9549iysf2dik09afixxy5brbxk1xfzb2r";
+
+  src = fetchFromGitHub {
+    owner = "johnath";
+    repo = "beep";
+    rev = "0d790fa45777896749a885c3b93b2c1476d59f20";
+    sha256 = "0dxz58an0sz5r82al5sc935y2z2k60rz12ikjvx7sz39rfirgfpc";
   };
 
-  makeFlags = "INSTALL_DIR=\${out}/bin/ MAN_DIR=\${out}/man/man1/";
+  patches = [ ./cve-2018-0492.patch ];
+
+  makeFlags = [
+    "INSTALL_DIR=${placeholder "out"}/bin/"
+    "MAN_DIR=${placeholder "out"}/man/man1/"
+  ];
 
   preInstall = ''
-    mkdir -p $out/bin
-    mkdir -p $out/man/man1
+    mkdir -p $out/{bin,man/man1}
   '';
-  meta = {
+
+  meta = with stdenv.lib; {
     description = "The advanced PC speaker beeper";
     homepage = http://www.johnath.com/beep/;
-    license = stdenv.lib.licenses.gpl2;
-    platforms = stdenv.lib.platforms.linux;
+    license = licenses.gpl2;
+    platforms = platforms.linux;
   };
 }