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