patch 750989 + patch
thanks

Hello,

Please find here a patch.

I rewrote apport-notifyd based on what ubuntu is doing in the
update-notifier code.

The patch is also bumping the debhelper compatibility so we are getting
the hardening flags automatically for the notifier daemon.

This should also fix #750471 and #760097

The debian/copyright file should probably also be adjusted.

Cheers,

Laurent Bigonville
diff -Nru apport-2.14.2/debian/apport-notifyd.c apport-2.14.2/debian/apport-notifyd.c
--- apport-2.14.2/debian/apport-notifyd.c	2014-09-10 11:56:22.000000000 +0200
+++ apport-2.14.2/debian/apport-notifyd.c	2014-09-23 00:23:47.000000000 +0200
@@ -1,116 +1,177 @@
-/*
-***************************************************************************
-*                  Copyright (C) Ritesh Raj Sarraf <[email protected]>       *
-*                                                                         *
-* This program is free software. You may use, modify, and redistribute it *
-* under the terms of the GNU General Public License as published   	  *
-* by the Free Software Foundation, either version 3 or (at your option)   *
-* any later version. This program is distributed without any warranty.    *
-***************************************************************************
-*/
-
-#include <sys/inotify.h>
-#include <syslog.h>
+/* apport-notifyd.c
+ * Copyright (C) 2004 Lukas Lipka <[email protected]>
+ *           (C) 2004 Michael Vogt <[email protected]>
+ *           (C) 2004 Michiel Sikkes <[email protected]>
+ *           (C) 2004-2009 Canonical
+ *           (C) 2014 Laurent Bigonville
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor
+ * Boston, MA  02110-1301 USA.
+ */
 #include <stdlib.h>
-#include <limits.h>
-#include <unistd.h>
-#include <string.h>
-
+#include <glib.h>
+#include <gio/gio.h>
 
-#define BUF_LEN (10 * (sizeof(struct inotify_event) + NAME_MAX + 1))
-#define PROG "apport-bug "
-#define CRASH_PATH "/var/crash/"
+/* the time when we check for fam events */
+#define TIMEOUT_FAM 1000*5 /* 5 sec */
 
-int checkFileExtn(const char* extn, const char* CRASH_EXTN)
+#define CRASHREPORT_HELPER "/usr/share/apport/apport-checkreports"
+#define CRASHREPORT_REPORT_APP "/usr/share/apport/apport-gtk"
+#define CRASHREPORT_DIR "/var/crash/"
+
+gboolean crashreport_pending = FALSE;
+
+void monitor_cb (GFileMonitor *handle,
+                 GFile *monitor_f,
+                 GFile *other_monitor_f,
+                 GFileMonitorEvent event_type,
+                 gpointer user_data)
 {
-	#define CRASH_EXTN ".crash"
-	size_t extnLength;
-	size_t apportLength;
 
-	extnLength = strlen(extn);
-	apportLength = strlen(CRASH_EXTN);
-	// syslog(LOG_NOTICE,"extnLength is %d and apportLength is %d\n", extnLength, apportLength);
+    gchar *info_uri = g_file_get_path(monitor_f);
+
+    /*
+    g_debug("inotify: info_uri: %s", info_uri);
+    g_debug("inotify: event_type: %i",event_type);
+    */
 
-	if(apportLength > extnLength) return 1;
+    /* we ignore lock file events because we can only get when a lock was
+     * taken, but not when it was removed */
+    if(g_str_has_suffix(info_uri, "lock"))
+        return;
+
+    if(g_str_has_prefix(info_uri, CRASHREPORT_DIR)) {
+        g_debug("crashreport found: %s", info_uri);
+        crashreport_pending = TRUE;
+    }
 
-	/* Check if it is a .crash file */
-	// syslog(LOG_NOTICE,"strcmp length is %s\n", &extn[extnLength - apportLength]);
-	return (strcmp(&extn[extnLength - apportLength], CRASH_EXTN)) == 0;
+    g_free(info_uri);
 }
 
-static void trapCrashFile(struct inotify_event *i)
+gboolean crashreport_check(gboolean system)
 {
+    gint exitcode = -1;
+    gchar *argv[] = { CRASHREPORT_HELPER, NULL, NULL };
 
-    char cmdStr[1024] = { NULL };
-    strcat(cmdStr, PROG);
-    strcat(cmdStr, CRASH_PATH);
-    strcat(cmdStr, i->name);
-    // syslog(LOG_DEBUG, "cmdStr is %s at event %d\n", cmdStr, i->mask);
+    if(system)
+        argv[1] = "--system";
 
-    if (checkFileExtn(i->name, CRASH_EXTN)) {
-	    // syslog(LOG_DEBUG, "File %s has extension %s\n", i->name, CRASH_EXTN);
-	    if (i->mask & IN_CREATE) {
-		    system(cmdStr);
-		    syslog(LOG_NOTICE, "cmdStr is %s at event %d\n", cmdStr, i->mask);
-	    }
-    } /* else {
-	    syslog(LOG_DEBUG, "File %s does not have extension %s\n", i->name, CRASH_EXTN);
-    } */
-
-    /*
-    if (i->mask & IN_CREATE)        system(cmdStr);
-    if (i->mask & IN_ATTRIB)        printf("IN_ATTRIB ");
-    if (i->mask & IN_MODIFY)        printf("IN_MODIFY ");
-    */
+    g_spawn_sync(NULL, argv, NULL, G_SPAWN_STDOUT_TO_DEV_NULL|G_SPAWN_STDERR_TO_DEV_NULL,
+                 NULL, NULL, NULL, NULL, &exitcode, NULL);
 
+    return (exitcode == 0); 
 }
 
+void dummy_child_watch (GPid pid, gint status, gpointer user_data)
+{
+    /*  We need to set the G_SPAWN_DO_NOT_REAP_CHILD when executing pkexec to
+     *  avoir double fork as polkit doesn't like it */
+    ;
+}
 
-int main()
+gboolean crashreport_process(gpointer user_data)
 {
-    int inotifyFd, wd;
-    char buf[BUF_LEN] __attribute__ ((aligned(4)));
-    ssize_t numRead;
-    char *p;
-    struct inotify_event *event;
+    GPid pid;
+    gboolean  retval;
+    GError *error = NULL;
+    gchar *argv[] = { NULL, NULL, NULL };
+
+    /* If there is no new file since the last time, do nothing, we still need
+     * to return TRUE so the processing can continue */
+    if(!crashreport_pending)
+        return TRUE;
+
+    /* don't do anything if apport-gtk is not installed */
+    if(!g_file_test(CRASHREPORT_REPORT_APP, G_FILE_TEST_IS_EXECUTABLE))
+        return TRUE;
+
+    g_debug("Let's see if we can do anything with the crash reports");
+
+    if(crashreport_check(TRUE))
+    {
+        g_debug("We have system crash reports");
+
+        argv[0] = "/usr/bin/pkexec";
+        argv[1] = CRASHREPORT_REPORT_APP;
+
+        retval = g_spawn_async (NULL, argv, NULL, G_SPAWN_STDOUT_TO_DEV_NULL|G_SPAWN_STDERR_TO_DEV_NULL|G_SPAWN_DO_NOT_REAP_CHILD,
+                                NULL, NULL, &pid, &error);
+
+        if (error == NULL && retval == TRUE) {
+            g_child_watch_add(pid, dummy_child_watch, NULL);
+        }
+    }
+    else if(crashreport_check(FALSE))
+    {
+        g_debug("We have crash reports for the user");
 
-    daemon(0,0);
+        argv[0] = CRASHREPORT_REPORT_APP;
 
-    /* Open a connection to the syslog server */
-    openlog("apport-notifyd",LOG_NOWAIT|LOG_PID,LOG_USER); 
+        retval = g_spawn_async (NULL, argv, NULL, G_SPAWN_STDOUT_TO_DEV_NULL|G_SPAWN_STDERR_TO_DEV_NULL|G_SPAWN_DO_NOT_REAP_CHILD,
+                                NULL, NULL, &pid, &error);
 
-    /* Sends a message to the syslog daemon */
-    syslog(LOG_NOTICE, "Successfully started daemon\n"); 
+        if (error == NULL && retval == TRUE) {
+            g_child_watch_add(pid, dummy_child_watch, NULL);
+        }
+    }
+    else
+        g_debug("Cannot do anything with the crash reports");
 
-    inotifyFd = inotify_init();                 /* Create inotify instance */
-    if (inotifyFd == -1)
-	syslog(LOG_NOTICE, "inotify_init");
+    crashreport_pending = FALSE;
 
-    // wd = inotify_add_watch(inotifyFd, CRASH_PATH, IN_CREATE|IN_ATTRIB|IN_MODIFY); /* We only care when a crash file gets created */
-    // wd = inotify_add_watch(inotifyFd, CRASH_PATH, IN_CLOSE_WRITE); /* We only care when a crash file gets created */
-    wd = inotify_add_watch(inotifyFd, CRASH_PATH, IN_CREATE); // We only care when a crash file gets created
+    if(error)
+        g_error_free(error);
 
-    if (wd == -1)	syslog(LOG_NOTICE, "inotify_add_watch");
+    return TRUE;
+}
 
-    for (;;) {                                  /* Read events forever */
-        numRead = read(inotifyFd, buf, BUF_LEN);
-        if (numRead == 0)
-            syslog(LOG_NOTICE, "read() from inotify fd returned 0!");
+GFileMonitor* monitor_init (void)
+{
+    GFileMonitor *monitor_handle;
+    GFile *filepath;
 
-        if (numRead == -1)
-            syslog(LOG_DEBUG, "read");
+    filepath = g_file_new_for_path(CRASHREPORT_DIR);
 
-        syslog(LOG_DEBUG, "Read %ld bytes from inotify fd\n", (long) numRead);
+    monitor_handle = g_file_monitor_directory(filepath, G_FILE_MONITOR_NONE, NULL, NULL);
+    if(monitor_handle)
+        g_signal_connect(monitor_handle, "changed", (GCallback)monitor_cb, NULL);
+    else
+        g_error("Cannot monitor directory %s", CRASHREPORT_DIR);
 
-        /* Process all of the events in buffer returned by read() */
+    g_timeout_add(TIMEOUT_FAM, (GSourceFunc)crashreport_process, NULL);
 
-        for (p = buf; p < buf + numRead; ) {
-            event = (struct inotify_event *) p;
-            trapCrashFile(event);
-	    syslog(LOG_NOTICE, "Got invoked\n");
+    g_object_unref(filepath);
 
-            p += sizeof(struct inotify_event) + event->len + 1;
-        }
-    }
-    closelog();
+    return monitor_handle;
 }
+
+int main (int argc, char **argv)
+{
+    GMainLoop *mainloop;
+    GFileMonitor *monitor_handle;
+
+    mainloop = g_main_loop_new(NULL, FALSE);
+
+    monitor_handle = monitor_init();
+
+    g_main_loop_run(mainloop);
+
+    g_main_loop_unref(mainloop);
+    g_object_unref(monitor_handle);
+        
+    return EXIT_SUCCESS;
+}
+
+/* vim:set sts=4 sw=4 et: */
diff -Nru apport-2.14.2/debian/compat apport-2.14.2/debian/compat
--- apport-2.14.2/debian/compat	2012-12-21 18:11:45.000000000 +0100
+++ apport-2.14.2/debian/compat	2014-09-23 00:23:29.000000000 +0200
@@ -1 +1 @@
-7
+9
diff -Nru apport-2.14.2/debian/control apport-2.14.2/debian/control
--- apport-2.14.2/debian/control	2014-06-02 08:29:58.000000000 +0200
+++ apport-2.14.2/debian/control	2014-09-23 00:23:29.000000000 +0200
@@ -1,10 +1,12 @@
 Source: apport
 Section: utils
 Priority: optional
-Build-Depends: debhelper (>= 7.0.50~),
+Build-Depends: debhelper (>= 9),
  gdb,
  python-twisted-core,
  gir1.2-glib-2.0 (>= 1.29.17),
+ pkg-config,
+ libglib2.0-dev,
  lsb-release,
  net-tools,
  xauth,
diff -Nru apport-2.14.2/debian/rules apport-2.14.2/debian/rules
--- apport-2.14.2/debian/rules	2014-05-11 08:58:53.000000000 +0200
+++ apport-2.14.2/debian/rules	2014-09-23 00:23:29.000000000 +0200
@@ -14,7 +14,7 @@
 override_dh_auto_build:
 	dh_auto_build
 	python3 setup.py build
-	gcc -Wall debian/apport-notifyd.c -o debian/apport-notifyd
+	gcc $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) `pkg-config --libs --cflags glib-2.0 gio-2.0 gobject-2.0` debian/apport-notifyd.c -o debian/apport-notifyd
 
 override_dh_installinit:
 	dh_installinit --error-handler=true

Reply via email to