[PATCH 1/1] Added exe field to audit core dump signal log
by Paul Davies C
Currently when the coredump signals are logged by the audit system , the
actual path to the executable is not logged. Without details of exe , the
system admin may not have an exact idea on what program failed.
This patch changes the audit_log_task() so that the path to the exe is also
logged.
Signed-off-by: Paul Davies C <pauldaviesc(a)gmail.com>
---
kernel/auditsc.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 9845cb3..988de72 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2353,6 +2353,7 @@ static void audit_log_task(struct audit_buffer *ab)
kuid_t auid, uid;
kgid_t gid;
unsigned int sessionid;
+ struct mm_struct *mm = current->mm;
auid = audit_get_loginuid(current);
sessionid = audit_get_sessionid(current);
@@ -2366,6 +2367,12 @@ static void audit_log_task(struct audit_buffer *ab)
audit_log_task_context(ab);
audit_log_format(ab, " pid=%d comm=", current->pid);
audit_log_untrustedstring(ab, current->comm);
+ if (mm) {
+ down_read(&mm->mmap_sem);
+ if (mm->exe_file)
+ audit_log_d_path(ab, " exe=", &mm->exe_file->f_path);
+ up_read(&mm->mmap_sem);
+ }
}
static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
--
1.7.9.5
9 years, 3 months
[PATCH] audit.h: remove the macro AUDIT_ARCH_ARMEB definition
by roy.qing.li@gmail.com
From: Li RongQing <roy.qing.li(a)gmail.com>
After 2f9783669 [ARM: 7412/1: audit: use only AUDIT_ARCH_ARM regardless
of endianness], no kernel user uses this macro;
Keeping this macro, only makes the compiling old version audit [before
changeset 931 Improve ARM and AARCH64 support] success, but the audit
program can not work with the kernel after 2f9783669 still,
since no syscall entry is enabled for AUDIT_ARCH_ARMEB in kernel.
so remove it to force to use the latest audit program
Signed-off-by: Li RongQing <roy.qing.li(a)gmail.com>
---
other workaround is to define AUDIT_ARCH_ARMEB as AUDIT_ARCH_ARM,
but it seems very strange
include/uapi/linux/audit.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index d3475e1..125aa49 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -351,7 +351,6 @@ enum {
#define AUDIT_ARCH_AARCH64 (EM_AARCH64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_ALPHA (EM_ALPHA|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_ARM (EM_ARM|__AUDIT_ARCH_LE)
-#define AUDIT_ARCH_ARMEB (EM_ARM)
#define AUDIT_ARCH_CRIS (EM_CRIS|__AUDIT_ARCH_LE)
#define AUDIT_ARCH_FRV (EM_FRV)
#define AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
--
2.1.0
9 years, 6 months
Re: log rendering in real time in audit-viewer
by Xeniya Muratova
I have fixed bugs in inserting new events, and also added real time rendering option in source dialog, and will be grateful for feedback.
diff -u -X ex or_src/audit-viewer.glade oav/src/audit-viewer.glade
--- or_src/audit-viewer.glade 2012-09-22 04:04:40.000000000 +0400
+++ oav/src/audit-viewer.glade 2015-03-30 12:13:06.810004999 +0300
@@ -2664,6 +2664,16 @@
</widget>
</child>
<child>
+ <widget class="GtkCheckButton" id="source_with_updating">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Render updates in real time</property>
+ <property name="use_underline">True</property>
+ <property name="response_id">0</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ </child>
+ <child>
<widget class="GtkVBox" id="vbox25">
<property name="visible">True</property>
<child>
diff -u -X ex or_src/event_source.py oav/src/event_source.py
--- or_src/event_source.py 2009-06-09 23:10:41.000000000 +0400
+++ oav/src/event_source.py 2015-03-30 12:41:11.028004422 +0300
@@ -19,7 +19,7 @@
import datetime
import os.path
import re
-
+import os
import auparse
__all__ = ('ClientEventSource', 'ClientWithRotatedEventSource',
@@ -95,7 +95,7 @@
'''A source of audit events, reading from an auparse parser.'''
def read_events(self, filters, wanted_fields, want_other_fields,
- keep_raw_records):
+ keep_raw_records, direction = None, tab = None):
'''Return a sequence of audit events read from parser.
Use filters to select events. Store wanted_fields in event.fields, the
@@ -265,6 +265,107 @@
def _create_parser(self):
return auparse.AuParser(auparse.AUSOURCE_BUFFER, self.str)
+class UpdatableEventSourceReader():
+
+ '''A separate reader of audit events, created for each tab of main window.
+ To be used with UpdatableEventSource.
+
+ '''
+
+ def __init__(self, event_source, tab):
+ self.event_source = event_source
+ self.tab = tab
+ self.up_file = open(event_source.base)
+ self.bottom_file = open(event_source.base)
+ self.up_file.seek(0, 2)
+ self.up_pos = self.down_pos = self.up_file.tell()
+ self.bytes = self.event_source.avg_line_length * self.event_source.chunk_size
+
+ def read_down(self):
+ ''' read older lines from file starting from self.down_pos'''
+ if os.path.exists(self.bottom_file.name):
+ if os.stat(self.bottom_file.name).st_ino != os.fstat(self.bottom_file.fileno()).st_ino:
+ self.bottom_file.close()
+ self.tab.want_read_down = False
+ return ''
+ if self.down_pos <= self.bytes:
+ self.bottom_file.seek(0)
+ lines = self.bottom_file.read(self.down_pos)
+ try:
+ files = os.listdir(os.path.dirname(self.event_source.base))
+ files = sorted(files, key = lambda x : os.stat(x).st_mtime)
+ filename = self.bottom_file.name
+ self.bottom_file.close()
+ self.bottom_file = open(files[files.index(filename) + 1])
+ self.bottom_file.seek(0, 2)
+ self.down_pos = self.bottom_file.tell()
+ except:
+ self.tab.want_read_down = False
+ else:
+ self.bottom_file.seek(self.down_pos - self.bytes)
+ lines = self.bottom_file.read(self.bytes)
+ lines = lines[lines.find('\n') + 1:]
+ self.down_pos -= len(lines)
+ return lines
+
+ def read_up(self):
+ '''try to read new lines if there are any after the previous reads'''
+ if os.path.exists(self.up_file.name):
+ if os.stat(self.up_file.name).st_ino != os.fstat(self.up_file.fileno()).st_ino:
+ self.up_file.close()
+ self.up_file = open(self.event_source.base)
+ self.up_pos = 0
+ else:
+ self.up_file.close()
+ self.tab.want_read_up = False
+ return ''
+ self.up_file.seek(0, 2)
+ file_end_pos = self.up_file.tell()
+ if self.up_pos != file_end_pos:
+ self.up_file.seek(self.up_pos)
+ if file_end_pos - self.up_pos > self.bytes*5:
+ lines = self.up_file.read(self.bytes)
+ file_end_pos = self.up_file.tell()
+ else:
+ lines = self.up_file.read()
+ if lines.endswith('\n'):
+ self.up_pos = file_end_pos
+ else:
+ lines = lines[:lines.rfind('\n') + 1]
+ self.up_pos += len(lines)
+ return lines
+ return ''
+
+
+class UpdatableEventSource(_ParserEventSource):
+
+ def __init__(self, base_file, chunk_size = 50, avg_line_length = 74):
+ self.chunk_size = chunk_size
+ self.avg_line_length = avg_line_length
+ self.readers = {}
+ self.base = base_file
+ self.current_lines = ''
+
+ def add_tab(self, tab):
+ self.readers[tab] = UpdatableEventSourceReader(self, tab)
+
+ def remove_tab(self, tab):
+ del self.readers[tab]
+
+ def read_events(self, filters, wanted_fields, want_other_fields,
+ keep_raw_records, direction, tab):
+ if direction == 'up':
+ self.current_lines = self.readers[tab].read_up()
+ else:
+ self.current_lines = self.readers[tab].read_down()
+ return _ParserEventSource.read_events(self, filters, wanted_fields, want_other_fields,
+ keep_raw_records)
+
+
+ def _create_parser(self):
+ return auparse.AuParser(auparse.AUSOURCE_BUFFER, self.current_lines)
+
+
def check_expression(expr):
'''Check expr.
diff -u -X ex or_src/list_tab.py oav/src/list_tab.py
--- or_src/list_tab.py 2009-12-19 10:00:00.000000000 +0300
+++ oav/src/list_tab.py 2015-03-30 13:26:44.579005427 +0300
@@ -28,6 +28,7 @@
from search_entry import SearchEntry
from tab import Tab
import util
+import event_source
__all__ = ('ListTab')
@@ -130,7 +131,7 @@
date_column_label = '__audit_viewer_date'
__list_number = 1
- def __init__(self, filters, main_window, will_refresh = False):
+ def __init__(self, filters, main_window, will_refresh = True):
Tab.__init__(self, filters, main_window, 'list_vbox')
# date_column_label == event date, None == all other columns
@@ -157,6 +158,13 @@
util.connect_and_run(self.selection, 'changed',
self.__selection_changed)
+ if isinstance(self.main_window.event_source, event_source.UpdatableEventSource):
+ self.main_window.event_source.add_tab(self)
+ self.want_read_up = True
+ self.want_read_down = True
+ self.__refresh_dont_read_events = False
+ self.refresh(False, 'up')
+ return
self.__refresh_dont_read_events = will_refresh
self.refresh()
self.__refresh_dont_read_events = False
@@ -191,20 +199,25 @@
% (util.filename_to_utf8(filename),
e.strerror))
- def refresh(self):
- event_sequence = self.__refresh_get_event_sequence()
+ def refresh(self, updating = False, direction = None):
+ if isinstance(self.main_window.event_source, event_source.UpdatableEventSource) and not updating:
+ self.want_read_down = True
+ self.want_read_up = True
+ self.main_window.event_source.readers[self] = event_source.UpdatableEventSourceReader(self.main_window.event_source, self)
+ event_sequence = self.__refresh_get_event_sequence(direction, self)
if event_sequence is None:
return
-
- if self.filters:
- t = _(', ').join(f.ui_text() for f in self.filters)
- else:
- t = _('None')
- self.list_filter_label.set_text(t)
- self.__refresh_update_tree_view()
+ if not updating:
+ if self.filters:
+ t = _(', ').join(f.ui_text() for f in self.filters)
+ else:
+ t = _('None')
+ self.list_filter_label.set_text(t)
+ self.__refresh_update_tree_view()
events = self.__refresh_collect_events(event_sequence)
- self.__refresh_update_store(events)
+ self.__refresh_update_store(events, updating)
+
def report_on_view(self):
self.main_window.new_report_tab(self.filters)
@@ -462,7 +475,7 @@
for record in event.records
for (key, value) in record.fields]))
- def __refresh_get_event_sequence(self):
+ def __refresh_get_event_sequence(self, direction = None, tab = None):
'''Return an event sequence (as if from self.main_window.read_events()).
Return None on error.
@@ -480,7 +493,7 @@
elif title is not self.date_column_label:
wanted_fields.add(title)
return self.main_window.read_events(self.filters, wanted_fields,
- want_other_fields, True)
+ want_other_fields, True, direction, tab)
def __refresh_update_tree_view(self):
'''Update self.list_tree_view for current configuration.
@@ -560,7 +573,32 @@
events.sort(key = lambda event: event[0], reverse = self.sort_reverse)
return events
- def __refresh_update_store(self, events):
+ def __insert_row(self, event):
+ ''' insert new row with event into self.store preserving sort order'''
+ it = None
+ if not isinstance(self.main_window.event_source, event_source.UpdatableEventSource):
+ it = self.store.append(event[1])
+ return it
+ if self.sort_by and self.sort_by not in self.columns:
+ self.sort_by = None
+ if self.sort_by:
+ sort_field = self.__field_columns.index(self.sort_by) + 1
+ for i in range(len(self.store)):
+ if event[0] > self.store[i][sort_field] and self.sort_reverse or \
+ event[0] <= self.store[i][sort_field] and not self.sort_reverse:
+ it = self.store.insert(i, event[1])
+ break
+ else:
+ for i in range(len(self.store)):
+ if event[1][0].id.sec > self.store[i][0].id.sec and self.sort_reverse or \
+ event[1][0].id.sec <= self.store[i][0].id.sec and not self.sort_reverse:
+ it = self.store.insert(i, event[1])
+ break
+ if not it:
+ it = self.store.append(event[1])
+ return it
+
+ def __refresh_update_store(self, events, updating = False):
'''Update self.store and related data.
events is the result of self.__refresh_collect_events().
@@ -571,11 +609,12 @@
key = pos.event_key
l = positions_for_event_key.setdefault(key, [])
l.append(pos)
- self.store.clear()
+ if not updating:
+ self.store.clear()
if (self.text_filter is None and
len(positions_for_event_key) == 0): # Fast path
for event in events:
- self.store.append(event[1])
+ self.__insert_row(event)
else:
event_to_it = {}
text_filter = self.text_filter
@@ -604,7 +643,8 @@
or (self.__other_column_event_text(event_tuple[0]).
find(self.text_filter) == -1))):
continue
- it = self.store.append(event_tuple)
+
+ it = self.__insert_row(event)
event_id = event_tuple[0].id
key = (event_id.serial, event_id.sec, event_id.milli)
if key in positions_for_event_key:
diff -u -X ex or_src/main.py oav/src/main.py
--- or_src/main.py 2008-06-26 00:17:59.000000000 +0400
+++ oav/src/main.py 2015-03-25 15:31:29.663932132 +0300
@@ -29,6 +29,7 @@
from main_window import MainWindow
import settings
import util
+import event_source
_ = gettext.gettext
@@ -48,12 +49,20 @@
help = _('do not attempt to start the privileged backend '
'for reading system audit logs'))
parser.set_defaults(unprivileged = False)
+ parser.add_option('-p', '--updatable', action = 'store_true',
+ dest = 'updatable',
+ help = _('read new lines from log '))
+ parser.set_defaults(updatable = False)
+ parser.add_option('-s', '--source', type = 'string',
+ dest = 'source',
+ help = _('path to log file '))
(options, args) = parser.parse_args()
gnome.init(settings.gettext_domain, settings.version)
gtk.glade.bindtextdomain(settings.gettext_domain, settings.localedir)
gtk.glade.textdomain(settings.gettext_domain)
+ ev_source = None
if options.unprivileged:
cl = None
else:
@@ -66,7 +75,9 @@
sys.exit(1)
except client.ClientNotAvailableError:
cl = None
+ if options.updatable:
+ ev_source = event_source.UpdatableEventSource(options.source)
- w = MainWindow(cl)
+ w = MainWindow(cl, ev_source)
if w.setup_initial_window(args):
gtk.main()
diff -u -X ex or_src/main_window.py oav/src/main_window.py
--- or_src/main_window.py 2008-08-19 14:38:16.000000000 +0400
+++ oav/src/main_window.py 2015-03-30 13:21:25.607005136 +0300
@@ -135,6 +135,8 @@
'''
try:
+ if isinstance(self.event_source, event_source.UpdatableEventSource):
+ self.updater = gobject.idle_add(self.update_tabs)
if isinstance(self.event_source, event_source.EmptyEventSource):
self.__event_error_report_only_one_push()
if self.client is not None:
@@ -246,7 +248,7 @@
return (filename, extension)
def read_events(self, filters, wanted_fields, want_other_fields,
- keep_raw_records):
+ keep_raw_records, direction = None, tab = None):
'''Read audit events.
Return a sequence of events, or None on error (without throwing
@@ -262,7 +264,7 @@
try:
return self.event_source.read_events(filters, wanted_fields,
want_other_fields,
- keep_raw_records)
+ keep_raw_records, direction, tab)
except IOError, e:
if (self.__event_error_report_only_one_depth == 0 or
not self.__event_error_reported):
@@ -381,16 +383,30 @@
'''End a region in which only one error message should be reported.'''
self.__event_error_report_only_one_depth -= 1
- def __refresh_all_tabs(self):
+ def update_tabs(self):
+ self.__refresh_all_tabs(True)
+ return True
+
+ def __refresh_all_tabs(self, updating = False):
'''Refresh all tabs, taking care to report errors only once.'''
self.__event_error_report_only_one_push()
try:
- for page_num in xrange(self.main_notebook.get_n_pages()):
- tab = self.__tab_objects[self.main_notebook
- .get_nth_page(page_num)]
- tab.refresh()
+ if not updating:
+ for page_num in xrange(self.main_notebook.get_n_pages()):
+ tab = self.__tab_objects[self.main_notebook
+ .get_nth_page(page_num)]
+ tab.refresh()
+ else:
+ for page_num in xrange(self.main_notebook.get_n_pages()):
+ tab = self.__tab_objects[self.main_notebook
+ .get_nth_page(page_num)]
+ if tab.want_read_up:
+ tab.refresh(True, 'up')
+ if tab.want_read_down:
+ tab.refresh(True, 'down')
finally:
self.__event_error_report_only_one_pop()
+ return True
def __menu_new_list_activate(self, *_):
self.new_list_tab([])
Only in oav/src/: patch
diff -u -X ex or_src/source_dialog.py oav/src/source_dialog.py
--- or_src/source_dialog.py 2009-06-09 22:35:26.000000000 +0400
+++ oav/src/source_dialog.py 2015-03-30 12:46:15.983005127 +0300
@@ -39,7 +39,8 @@
'source_path', 'source_path_browse',
'source_path_label',
'source_type_file', 'source_type_log',
- 'source_with_rotated')
+ 'source_with_rotated',
+ 'source_with_updating')
def __init__(self, parent, client):
DialogBase.__init__(self, 'source_dialog', parent)
@@ -58,6 +59,8 @@
self.__source_type_log_toggled)
util.connect_and_run(self.source_type_file, 'toggled',
self.__source_type_file_toggled)
+ util.connect_and_run(self.source_with_updating, 'toggled',
+ self.__source_with_updating_toggled)
self._setup_browse_button(self.source_path_browse, self.source_path,
_('Audit Log File'),
gtk.FILE_CHOOSER_ACTION_OPEN)
@@ -102,13 +105,20 @@
self.source_with_rotated.set_active(False)
self.source_type_file.set_active(True)
self.source_path.set_text(source.path)
+ elif isinstance(source, event_source.FileWithRotatedEventSource):
+ self.source_with_rotated.set_active(True)
+ self.source_type_file.set_active(True)
+ self.source_path.set_text(source.base)
else:
assert isinstance(source,
- event_source.FileWithRotatedEventSource), \
+ event_source.UpdatableEventSource), \
'Unexpected event source'
self.source_with_rotated.set_active(True)
+ self.source_with_rotated.set_sensitive(False)
+ self.source_type_log.set_sensitive(False)
self.source_type_file.set_active(True)
self.source_path.set_text(source.base)
+ self.source_with_updating.set_active(True)
def save(self, main_window):
'''Modify main_window to reflect dialog state.'''
@@ -124,7 +134,10 @@
source = event_source.ClientEventSource(self.client, name)
else:
path = self.source_path.get_text()
- if self.source_with_rotated.get_active():
+ if self.source_with_updating.get_active():
+ source = event_source.UpdatableEventSource(path)
+ main_window.updater = gobject.idle_add(main_window.update_tabs)
+ elif self.source_with_rotated.get_active():
source = event_source.FileWithRotatedEventSource(path)
else:
source = event_source.FileEventSource(path)
@@ -175,11 +188,21 @@
if it is not None:
self.source_log.set_active_iter(it)
+ def __source_with_updating_toggled(self, *_):
+ is_set = self.source_with_updating.get_active()
+ self.source_with_rotated.set_sensitive(not is_set)
+ self.source_type_log.set_sensitive(not is_set)
+ if is_set:
+ self.source_type_file.set_active(True)
+ self.source_type_log.set_active(False)
+ self.source_with_rotated.set_active(True)
+
def __source_type_file_toggled(self, *_):
util.set_sensitive_all(self.source_type_file.get_active(),
self.source_path_label, self.source_path,
self.source_path_browse)
+
def __window_destroy(self, *_):
self.emit('destroy')
return False
diff -u -X ex or_src/event_source.py oav/src/event_source.py
--- or_src/event_source.py 2009-06-09 23:10:41.000000000 +0400
+++ oav/src/event_source.py 2015-03-30 12:41:11.028004422 +0300
@@ -19,7 +19,7 @@
import datetime
import os.path
import re
-
+import os
import auparse
__all__ = ('ClientEventSource', 'ClientWithRotatedEventSource',
@@ -95,7 +95,7 @@
'''A source of audit events, reading from an auparse parser.'''
def read_events(self, filters, wanted_fields, want_other_fields,
- keep_raw_records):
+ keep_raw_records, direction = None, tab = None):
'''Return a sequence of audit events read from parser.
Use filters to select events. Store wanted_fields in event.fields, the
@@ -265,6 +265,107 @@
def _create_parser(self):
return auparse.AuParser(auparse.AUSOURCE_BUFFER, self.str)
+class UpdatableEventSourceReader():
+
+ '''A separate reader of audit events, created for each tab of main window.
+ To be used with UpdatableEventSource.
+
+ '''
+
+ def __init__(self, event_source, tab):
+ self.event_source = event_source
+ self.tab = tab
+ self.up_file = open(event_source.base)
+ self.bottom_file = open(event_source.base)
+ self.up_file.seek(0, 2)
+ self.up_pos = self.down_pos = self.up_file.tell()
+ self.bytes = self.event_source.avg_line_length * self.event_source.chunk_size
+
+ def read_down(self):
+ ''' read older lines from file starting from self.down_pos'''
+ if os.path.exists(self.bottom_file.name):
+ if os.stat(self.bottom_file.name).st_ino != os.fstat(self.bottom_file.fileno()).st_ino:
+ self.bottom_file.close()
+ self.tab.want_read_down = False
+ return ''
+ if self.down_pos <= self.bytes:
+ self.bottom_file.seek(0)
+ lines = self.bottom_file.read(self.down_pos)
+ try:
+ files = os.listdir(os.path.dirname(self.event_source.base))
+ files = sorted(files, key = lambda x : os.stat(x).st_mtime)
+ filename = self.bottom_file.name
+ self.bottom_file.close()
+ self.bottom_file = open(files[files.index(filename) + 1])
+ self.bottom_file.seek(0, 2)
+ self.down_pos = self.bottom_file.tell()
+ except:
+ self.tab.want_read_down = False
+ else:
+ self.bottom_file.seek(self.down_pos - self.bytes)
+ lines = self.bottom_file.read(self.bytes)
+ lines = lines[lines.find('\n') + 1:]
+ self.down_pos -= len(lines)
+ return lines
+
+ def read_up(self):
+ '''try to read new lines if there are any after the previous reads'''
+ if os.path.exists(self.up_file.name):
+ if os.stat(self.up_file.name).st_ino != os.fstat(self.up_file.fileno()).st_ino:
+ self.up_file.close()
+ self.up_file = open(self.event_source.base)
+ self.up_pos = 0
+ else:
+ self.up_file.close()
+ self.tab.want_read_up = False
+ return ''
+ self.up_file.seek(0, 2)
+ file_end_pos = self.up_file.tell()
+ if self.up_pos != file_end_pos:
+ self.up_file.seek(self.up_pos)
+ if file_end_pos - self.up_pos > self.bytes*5:
+ lines = self.up_file.read(self.bytes)
+ file_end_pos = self.up_file.tell()
+ else:
+ lines = self.up_file.read()
+ if lines.endswith('\n'):
+ self.up_pos = file_end_pos
+ else:
+ lines = lines[:lines.rfind('\n') + 1]
+ self.up_pos += len(lines)
+ return lines
+ return ''
+
+
+class UpdatableEventSource(_ParserEventSource):
+
+ def __init__(self, base_file, chunk_size = 50, avg_line_length = 74):
+ self.chunk_size = chunk_size
+ self.avg_line_length = avg_line_length
+ self.readers = {}
+ self.base = base_file
+ self.current_lines = ''
+
+ def add_tab(self, tab):
+ self.readers[tab] = UpdatableEventSourceReader(self, tab)
+
+ def remove_tab(self, tab):
+ del self.readers[tab]
+
+ def read_events(self, filters, wanted_fields, want_other_fields,
+ keep_raw_records, direction, tab):
+ if direction == 'up':
+ self.current_lines = self.readers[tab].read_up()
+ else:
+ self.current_lines = self.readers[tab].read_down()
+ return _ParserEventSource.read_events(self, filters, wanted_fields, want_other_fields,
+ keep_raw_records)
+
+
+ def _create_parser(self):
+ return auparse.AuParser(auparse.AUSOURCE_BUFFER, self.current_lines)
+
+
def check_expression(expr):
'''Check expr.
diff -u -X ex or_src/list_tab.py oav/src/list_tab.py
--- or_src/list_tab.py 2009-12-19 10:00:00.000000000 +0300
+++ oav/src/list_tab.py 2015-03-30 13:26:44.579005427 +0300
@@ -28,6 +28,7 @@
from search_entry import SearchEntry
from tab import Tab
import util
+import event_source
__all__ = ('ListTab')
@@ -130,7 +131,7 @@
date_column_label = '__audit_viewer_date'
__list_number = 1
- def __init__(self, filters, main_window, will_refresh = False):
+ def __init__(self, filters, main_window, will_refresh = True):
Tab.__init__(self, filters, main_window, 'list_vbox')
# date_column_label == event date, None == all other columns
@@ -157,6 +158,13 @@
util.connect_and_run(self.selection, 'changed',
self.__selection_changed)
+ if isinstance(self.main_window.event_source, event_source.UpdatableEventSource):
+ self.main_window.event_source.add_tab(self)
+ self.want_read_up = True
+ self.want_read_down = True
+ self.__refresh_dont_read_events = False
+ self.refresh(False, 'up')
+ return
self.__refresh_dont_read_events = will_refresh
self.refresh()
self.__refresh_dont_read_events = False
@@ -191,20 +199,25 @@
% (util.filename_to_utf8(filename),
e.strerror))
- def refresh(self):
- event_sequence = self.__refresh_get_event_sequence()
+ def refresh(self, updating = False, direction = None):
+ if isinstance(self.main_window.event_source, event_source.UpdatableEventSource) and not updating:
+ self.want_read_down = True
+ self.want_read_up = True
+ self.main_window.event_source.readers[self] = event_source.UpdatableEventSourceReader(self.main_window.event_source, self)
+ event_sequence = self.__refresh_get_event_sequence(direction, self)
if event_sequence is None:
return
-
- if self.filters:
- t = _(', ').join(f.ui_text() for f in self.filters)
- else:
- t = _('None')
- self.list_filter_label.set_text(t)
- self.__refresh_update_tree_view()
+ if not updating:
+ if self.filters:
+ t = _(', ').join(f.ui_text() for f in self.filters)
+ else:
+ t = _('None')
+ self.list_filter_label.set_text(t)
+ self.__refresh_update_tree_view()
events = self.__refresh_collect_events(event_sequence)
- self.__refresh_update_store(events)
+ self.__refresh_update_store(events, updating)
+
def report_on_view(self):
self.main_window.new_report_tab(self.filters)
@@ -462,7 +475,7 @@
for record in event.records
for (key, value) in record.fields]))
- def __refresh_get_event_sequence(self):
+ def __refresh_get_event_sequence(self, direction = None, tab = None):
'''Return an event sequence (as if from self.main_window.read_events()).
Return None on error.
@@ -480,7 +493,7 @@
elif title is not self.date_column_label:
wanted_fields.add(title)
return self.main_window.read_events(self.filters, wanted_fields,
- want_other_fields, True)
+ want_other_fields, True, direction, tab)
def __refresh_update_tree_view(self):
'''Update self.list_tree_view for current configuration.
@@ -560,7 +573,32 @@
events.sort(key = lambda event: event[0], reverse = self.sort_reverse)
return events
- def __refresh_update_store(self, events):
+ def __insert_row(self, event):
+ ''' insert new row with event into self.store preserving sort order'''
+ it = None
+ if not isinstance(self.main_window.event_source, event_source.UpdatableEventSource):
+ it = self.store.append(event[1])
+ return it
+ if self.sort_by and self.sort_by not in self.columns:
+ self.sort_by = None
+ if self.sort_by:
+ sort_field = self.__field_columns.index(self.sort_by) + 1
+ for i in range(len(self.store)):
+ if event[0] > self.store[i][sort_field] and self.sort_reverse or \
+ event[0] <= self.store[i][sort_field] and not self.sort_reverse:
+ it = self.store.insert(i, event[1])
+ break
+ else:
+ for i in range(len(self.store)):
+ if event[1][0].id.sec > self.store[i][0].id.sec and self.sort_reverse or \
+ event[1][0].id.sec <= self.store[i][0].id.sec and not self.sort_reverse:
+ it = self.store.insert(i, event[1])
+ break
+ if not it:
+ it = self.store.append(event[1])
+ return it
+
+ def __refresh_update_store(self, events, updating = False):
'''Update self.store and related data.
events is the result of self.__refresh_collect_events().
@@ -571,11 +609,12 @@
key = pos.event_key
l = positions_for_event_key.setdefault(key, [])
l.append(pos)
- self.store.clear()
+ if not updating:
+ self.store.clear()
if (self.text_filter is None and
len(positions_for_event_key) == 0): # Fast path
for event in events:
- self.store.append(event[1])
+ self.__insert_row(event)
else:
event_to_it = {}
text_filter = self.text_filter
@@ -604,7 +643,8 @@
or (self.__other_column_event_text(event_tuple[0]).
find(self.text_filter) == -1))):
continue
- it = self.store.append(event_tuple)
+
+ it = self.__insert_row(event)
event_id = event_tuple[0].id
key = (event_id.serial, event_id.sec, event_id.milli)
if key in positions_for_event_key:
diff -u -X ex or_src/main.py oav/src/main.py
--- or_src/main.py 2008-06-26 00:17:59.000000000 +0400
+++ oav/src/main.py 2015-03-25 15:31:29.663932132 +0300
@@ -29,6 +29,7 @@
from main_window import MainWindow
import settings
import util
+import event_source
_ = gettext.gettext
@@ -48,12 +49,20 @@
help = _('do not attempt to start the privileged backend '
'for reading system audit logs'))
parser.set_defaults(unprivileged = False)
+ parser.add_option('-p', '--updatable', action = 'store_true',
+ dest = 'updatable',
+ help = _('read new lines from log '))
+ parser.set_defaults(updatable = False)
+ parser.add_option('-s', '--source', type = 'string',
+ dest = 'source',
+ help = _('path to log file '))
(options, args) = parser.parse_args()
gnome.init(settings.gettext_domain, settings.version)
gtk.glade.bindtextdomain(settings.gettext_domain, settings.localedir)
gtk.glade.textdomain(settings.gettext_domain)
+ ev_source = None
if options.unprivileged:
cl = None
else:
@@ -66,7 +75,9 @@
sys.exit(1)
except client.ClientNotAvailableError:
cl = None
+ if options.updatable:
+ ev_source = event_source.UpdatableEventSource(options.source)
- w = MainWindow(cl)
+ w = MainWindow(cl, ev_source)
if w.setup_initial_window(args):
gtk.main()
diff -u -X ex or_src/main_window.py oav/src/main_window.py
--- or_src/main_window.py 2008-08-19 14:38:16.000000000 +0400
+++ oav/src/main_window.py 2015-03-30 13:21:25.607005136 +0300
@@ -135,6 +135,8 @@
'''
try:
+ if isinstance(self.event_source, event_source.UpdatableEventSource):
+ self.updater = gobject.idle_add(self.update_tabs)
if isinstance(self.event_source, event_source.EmptyEventSource):
self.__event_error_report_only_one_push()
if self.client is not None:
@@ -246,7 +248,7 @@
return (filename, extension)
def read_events(self, filters, wanted_fields, want_other_fields,
- keep_raw_records):
+ keep_raw_records, direction = None, tab = None):
'''Read audit events.
Return a sequence of events, or None on error (without throwing
@@ -262,7 +264,7 @@
try:
return self.event_source.read_events(filters, wanted_fields,
want_other_fields,
- keep_raw_records)
+ keep_raw_records, direction, tab)
except IOError, e:
if (self.__event_error_report_only_one_depth == 0 or
not self.__event_error_reported):
@@ -381,16 +383,30 @@
'''End a region in which only one error message should be reported.'''
self.__event_error_report_only_one_depth -= 1
- def __refresh_all_tabs(self):
+ def update_tabs(self):
+ self.__refresh_all_tabs(True)
+ return True
+
+ def __refresh_all_tabs(self, updating = False):
'''Refresh all tabs, taking care to report errors only once.'''
self.__event_error_report_only_one_push()
try:
- for page_num in xrange(self.main_notebook.get_n_pages()):
- tab = self.__tab_objects[self.main_notebook
- .get_nth_page(page_num)]
- tab.refresh()
+ if not updating:
+ for page_num in xrange(self.main_notebook.get_n_pages()):
+ tab = self.__tab_objects[self.main_notebook
+ .get_nth_page(page_num)]
+ tab.refresh()
+ else:
+ for page_num in xrange(self.main_notebook.get_n_pages()):
+ tab = self.__tab_objects[self.main_notebook
+ .get_nth_page(page_num)]
+ if tab.want_read_up:
+ tab.refresh(True, 'up')
+ if tab.want_read_down:
+ tab.refresh(True, 'down')
finally:
self.__event_error_report_only_one_pop()
+ return True
def __menu_new_list_activate(self, *_):
self.new_list_tab([])
----- Исходное сообщение -----
От: "mitr" <mitr(a)redhat.com>
Кому: "Xeniya Muratova" <muratova(a)itsirius.su>
Копия: "linux-audit" <linux-audit(a)redhat.com>
Отправленные: Среда, 4 Март 2015 г 20:50:53
Тема: Re: log rendering in real time in audit-viewer
Hello,
> Hello Miloslav, and all the guys!
>
> We use audit-viewer for events monitoring.
> Unfortunately, if some log is rather big it takes to much time for
> audit-viewer to parse and render it.
> Besides, we need to render log updates in real time, i.e. when a new line
> appears in a log, it should appear in a viewer too.
> Can you suggest the better way to extend audit-viewer to meet these
> requirements?
Well, write the code? Something like inotify could be useful. There isn’t any hidden switch to enable these features, if that is what you are asking.
As for performance, I may have missed something but I think I have squeezed as much as can be done with Python; improving performance further would very likely require a C extension.
(audit-viewer is a PyGtk2 application, and at I’m afraid I don’t currently have plans to port it to GTK+3/gobject-introspection or do any other non-trivial work on the project, at least in the near term.)
Mirek
9 years, 7 months
Re: [PATCH] log rendering in real time in audit-viewer
by Xeniya Muratova
This code extends audit-viewer _ParserEventSource to produce UpdatableEventSource (unprivileged).
I have not added this option to SourceDialog, so to see how updating works command line call may be used (python main.py -p -s /path/to/log)
diff -u -X ex or_src/event_source.py oav/src/event_source.py
--- or_src/event_source.py 2009-06-09 23:10:41.000000000 +0400
+++ oav/src/event_source.py 2015-03-25 16:09:59.933965077 +0300
@@ -19,7 +19,7 @@
import datetime
import os.path
import re
-
+import os
import auparse
__all__ = ('ClientEventSource', 'ClientWithRotatedEventSource',
@@ -95,7 +95,7 @@
'''A source of audit events, reading from an auparse parser.'''
def read_events(self, filters, wanted_fields, want_other_fields,
- keep_raw_records):
+ keep_raw_records, direction = None, tab = None):
'''Return a sequence of audit events read from parser.
Use filters to select events. Store wanted_fields in event.fields, the
@@ -265,6 +265,106 @@
def _create_parser(self):
return auparse.AuParser(auparse.AUSOURCE_BUFFER, self.str)
+class UpdatableEventSourceReader():
+
+ '''A separate reader of audit events, created for each tab of main window.
+ To be used with UpdatableEventSource.
+
+ '''
+
+ def __init__(self, event_source, tab):
+ self.event_source = event_source
+ self.tab = tab
+ self.chunk_size = event_source.chunk_size
+ self.up_file = open(event_source.base_file)
+ self.bottom_file = open(event_source.base_file)
+ self.up_file.seek(0, 2)
+ self.up_pos = self.down_pos = self.up_file.tell()
+
+ def read_down(self):
+ ''' read older lines from file starting from self.down_pos'''
+ if os.path.exists(self.bottom_file.name):
+ if os.stat(self.bottom_file.name).st_ino != os.fstat(self.bottom_file.fileno()).st_ino:
+ self.bottom_file.close()
+ self.tab.want_read_down = False
+ return ''
+ if self.down_pos <= self.event_source.avg_line_length * self.chunk_size:
+ self.bottom_file.seek(self.down_pos)
+ lines = self.bottom_file.read(self.down_pos)
+ try:
+ files = os.listdir(os.path.dirname(self.event_source.base_file))
+ files = sorted(files, key = lambda x : os.stat(x).st_mtime)
+ filename = self.bottom_file.name
+ self.bottom_file.close()
+ self.bottom_file = open(files[files.index(filename) + 1])
+ except:
+ self.tab.want_read_down = False
+ return ''
+ else:
+ self.bottom_file.seek(self.down_pos - self.event_source.avg_line_length * self.chunk_size)
+ lines = self.bottom_file.read(self.event_source.avg_line_length * self.chunk_size)
+ lines = lines[lines.find('\n') + 1:]
+ self.down_pos -= len(lines)
+ return lines
+
+ def read_up(self):
+ '''try to read new lines if there any after the previous read'''
+ if os.path.exists(self.up_file.name):
+ if os.stat(self.up_file.name).st_ino != os.fstat(self.up_file.fileno()).st_ino:
+ self.up_file.close()
+ self.up_file = open(self.event_source.base_file)
+ self.up_pos = 0
+ else:
+ self.up_file.close()
+ self.tab.want_read_up = False
+ return ''
+ self.up_file.seek(0, 2)
+ file_end_pos = self.up_file.tell()
+ if self.up_pos != file_end_pos:
+ self.up_file.seek(self.up_pos)
+ if file_end_pos - self.up_pos > self.event_source.avg_line_length*self.chunk_size*5:
+ lines = self.up_file.read(self.event_source.avg_line_length*self.chunk_size)
+ file_end_pos = self.up_file.tell()
+ else:
+ lines = self.up_file.read()
+ if lines.endswith('\n'):
+ self.up_pos = file_end_pos
+ else:
+ lines = lines[:lines.rfind('\n') + 1]
+ self.up_pos += len(lines)
+ return lines
+ return ''
+
+
+class UpdatableEventSource(_ParserEventSource):
+
+ def __init__(self, base_file, chunk_size = 50, avg_line_length = 74):
+ self.chunk_size = chunk_size
+ self.avg_line_length = avg_line_length
+ self.readers = {}
+ self.base_file = base_file
+ self.current_lines = ''
+
+ def add_tab(self, tab):
+ self.readers[tab] = UpdatableEventSourceReader(self, tab)
+
+ def remove_tab(self, tab):
+ del self.readers[tab]
+
+ def read_events(self, filters, wanted_fields, want_other_fields,
+ keep_raw_records, direction, tab):
+ if direction == 'up':
+ self.current_lines = self.readers[tab].read_up()
+ else:
+ self.current_lines = self.readers[tab].read_down()
+ return _ParserEventSource.read_events(self, filters, wanted_fields, want_other_fields,
+ keep_raw_records)
+
+
+ def _create_parser(self):
+ return auparse.AuParser(auparse.AUSOURCE_BUFFER, self.current_lines)
+
+
def check_expression(expr):
'''Check expr.
diff -u -X ex or_src/list_tab.py oav/src/list_tab.py
--- or_src/list_tab.py 2009-12-19 10:00:00.000000000 +0300
+++ oav/src/list_tab.py 2015-03-25 15:42:07.797941743 +0300
@@ -28,6 +28,7 @@
from search_entry import SearchEntry
from tab import Tab
import util
+import event_source
__all__ = ('ListTab')
@@ -130,7 +131,7 @@
date_column_label = '__audit_viewer_date'
__list_number = 1
- def __init__(self, filters, main_window, will_refresh = False):
+ def __init__(self, filters, main_window, will_refresh = True):
Tab.__init__(self, filters, main_window, 'list_vbox')
# date_column_label == event date, None == all other columns
@@ -157,6 +158,13 @@
util.connect_and_run(self.selection, 'changed',
self.__selection_changed)
+ if isinstance(self.main_window.event_source, event_source.UpdatableEventSource):
+ self.main_window.event_source.add_tab(self)
+ self.want_read_up = True
+ self.want_read_down = True
+ self.__refresh_dont_read_events = False
+ self.refresh(True, 'up', True)
+ return
self.__refresh_dont_read_events = will_refresh
self.refresh()
self.__refresh_dont_read_events = False
@@ -191,20 +199,21 @@
% (util.filename_to_utf8(filename),
e.strerror))
- def refresh(self):
- event_sequence = self.__refresh_get_event_sequence()
+ def refresh(self, updatable = False, direction = None, init = False):
+ event_sequence = self.__refresh_get_event_sequence(direction, self)
if event_sequence is None:
return
-
- if self.filters:
- t = _(', ').join(f.ui_text() for f in self.filters)
- else:
- t = _('None')
- self.list_filter_label.set_text(t)
- self.__refresh_update_tree_view()
+ if not updatable or init:
+ if self.filters:
+ t = _(', ').join(f.ui_text() for f in self.filters)
+ else:
+ t = _('None')
+ self.list_filter_label.set_text(t)
+ self.__refresh_update_tree_view()
events = self.__refresh_collect_events(event_sequence)
- self.__refresh_update_store(events)
+ self.__refresh_update_store(events, updatable, direction)
+
def report_on_view(self):
self.main_window.new_report_tab(self.filters)
@@ -462,7 +471,7 @@
for record in event.records
for (key, value) in record.fields]))
- def __refresh_get_event_sequence(self):
+ def __refresh_get_event_sequence(self, direction = None, tab = None):
'''Return an event sequence (as if from self.main_window.read_events()).
Return None on error.
@@ -480,7 +489,7 @@
elif title is not self.date_column_label:
wanted_fields.add(title)
return self.main_window.read_events(self.filters, wanted_fields,
- want_other_fields, True)
+ want_other_fields, True, direction, tab)
def __refresh_update_tree_view(self):
'''Update self.list_tree_view for current configuration.
@@ -560,7 +569,32 @@
events.sort(key = lambda event: event[0], reverse = self.sort_reverse)
return events
- def __refresh_update_store(self, events):
+ def __insert_row(self, event, direction):
+ ''' insert new row with event into self.store preserving sort order'''
+ it = None
+ if not self.sort_by:
+ if self.sort_reverse:
+ if direction == 'up':
+ it = self.store.insert(0, event[1])
+ else:
+ it = self.store.append(event[1])
+ else:
+ if direction == 'down':
+ it = self.store.insert(0, event[1])
+ else:
+ it = self.store.append(event[1])
+ else:
+ sort_field = self.__field_columns.index(self.sort_by) + 1
+ for i in range(len(self.store)):
+ if event[1][sort_field] <= self.store[i][sort_field] and self.sort_reverse or \
+ event[1][sort_field] > self.store[i][sort_field] and not self.sort_reverse:
+ it = self.store.insert(i, event[1])
+ break
+ if not it:
+ it = self.store.append(event[1])
+ return it
+
+ def __refresh_update_store(self, events, updatable = False, direction = None):
'''Update self.store and related data.
events is the result of self.__refresh_collect_events().
@@ -571,11 +605,15 @@
key = pos.event_key
l = positions_for_event_key.setdefault(key, [])
l.append(pos)
- self.store.clear()
+ if not updatable:
+ self.store.clear()
if (self.text_filter is None and
len(positions_for_event_key) == 0): # Fast path
for event in events:
- self.store.append(event[1])
+ if not updatable:
+ self.store.append(event[1])
+ else:
+ self.__insert_row(event, direction)
else:
event_to_it = {}
text_filter = self.text_filter
@@ -604,7 +642,10 @@
or (self.__other_column_event_text(event_tuple[0]).
find(self.text_filter) == -1))):
continue
- it = self.store.append(event_tuple)
+ if not updatable:
+ it = self.store.append(event_tuple)
+ else:
+ it = self.__insert_row(event, direction)
event_id = event_tuple[0].id
key = (event_id.serial, event_id.sec, event_id.milli)
if key in positions_for_event_key:
diff -u -X ex or_src/main.py oav/src/main.py
--- or_src/main.py 2008-06-26 00:17:59.000000000 +0400
+++ oav/src/main.py 2015-03-25 15:31:29.663932132 +0300
@@ -29,6 +29,7 @@
from main_window import MainWindow
import settings
import util
+import event_source
_ = gettext.gettext
@@ -48,12 +49,20 @@
help = _('do not attempt to start the privileged backend '
'for reading system audit logs'))
parser.set_defaults(unprivileged = False)
+ parser.add_option('-p', '--updatable', action = 'store_true',
+ dest = 'updatable',
+ help = _('read new lines from log '))
+ parser.set_defaults(updatable = False)
+ parser.add_option('-s', '--source', type = 'string',
+ dest = 'source',
+ help = _('path to log file '))
(options, args) = parser.parse_args()
gnome.init(settings.gettext_domain, settings.version)
gtk.glade.bindtextdomain(settings.gettext_domain, settings.localedir)
gtk.glade.textdomain(settings.gettext_domain)
+ ev_source = None
if options.unprivileged:
cl = None
else:
@@ -66,7 +75,9 @@
sys.exit(1)
except client.ClientNotAvailableError:
cl = None
+ if options.updatable:
+ ev_source = event_source.UpdatableEventSource(options.source)
- w = MainWindow(cl)
+ w = MainWindow(cl, ev_source)
if w.setup_initial_window(args):
gtk.main()
diff -u -X ex or_src/main_window.py oav/src/main_window.py
--- or_src/main_window.py 2008-08-19 14:38:16.000000000 +0400
+++ oav/src/main_window.py 2015-03-23 19:13:04.399266459 +0300
@@ -135,6 +135,8 @@
'''
try:
+ if isinstance(self.event_source, event_source.UpdatableEventSource):
+ self.updater = gobject.idle_add(self.__refresh_all_tabs, True)
if isinstance(self.event_source, event_source.EmptyEventSource):
self.__event_error_report_only_one_push()
if self.client is not None:
@@ -246,7 +248,7 @@
return (filename, extension)
def read_events(self, filters, wanted_fields, want_other_fields,
- keep_raw_records):
+ keep_raw_records, direction = None, tab = None):
'''Read audit events.
Return a sequence of events, or None on error (without throwing
@@ -262,7 +264,7 @@
try:
return self.event_source.read_events(filters, wanted_fields,
want_other_fields,
- keep_raw_records)
+ keep_raw_records, direction, tab)
except IOError, e:
if (self.__event_error_report_only_one_depth == 0 or
not self.__event_error_reported):
@@ -381,16 +383,24 @@
'''End a region in which only one error message should be reported.'''
self.__event_error_report_only_one_depth -= 1
- def __refresh_all_tabs(self):
+ def __refresh_all_tabs(self, updatable = False):
'''Refresh all tabs, taking care to report errors only once.'''
self.__event_error_report_only_one_push()
try:
- for page_num in xrange(self.main_notebook.get_n_pages()):
- tab = self.__tab_objects[self.main_notebook
- .get_nth_page(page_num)]
- tab.refresh()
+ if not updatable:
+ for page_num in xrange(self.main_notebook.get_n_pages()):
+ tab = self.__tab_objects[self.main_notebook
+ .get_nth_page(page_num)]
+ tab.refresh()
+ else:
+ for page_num in xrange(self.main_notebook.get_n_pages()):
+ tab = self.__tab_objects[self.main_notebook
+ .get_nth_page(page_num)]
+ tab.refresh(True, 'up')
+ tab.refresh(True, 'down')
finally:
self.__event_error_report_only_one_pop()
+ return True
def __menu_new_list_activate(self, *_):
self.new_list_tab([])
----- Исходное сообщение -----
От: "mitr" <mitr(a)redhat.com>
Кому: "Xeniya Muratova" <muratova(a)itsirius.su>
Копия: "linux-audit" <linux-audit(a)redhat.com>
Отправленные: Среда, 4 Март 2015 г 20:50:53
Тема: Re: log rendering in real time in audit-viewer
Hello,
> Hello Miloslav, and all the guys!
>
> We use audit-viewer for events monitoring.
> Unfortunately, if some log is rather big it takes to much time for
> audit-viewer to parse and render it.
> Besides, we need to render log updates in real time, i.e. when a new line
> appears in a log, it should appear in a viewer too.
> Can you suggest the better way to extend audit-viewer to meet these
> requirements?
Well, write the code? Something like inotify could be useful. There isn’t any hidden switch to enable these features, if that is what you are asking.
As for performance, I may have missed something but I think I have squeezed as much as can be done with Python; improving performance further would very likely require a C extension.
(audit-viewer is a PyGtk2 application, and at I’m afraid I don’t currently have plans to port it to GTK+3/gobject-introspection or do any other non-trivial work on the project, at least in the near term.)
Mirek
9 years, 7 months
[PATCH] audit: Remove condition which always evaluates to false
by Pranith Kumar
After commit 3e1d0bb6224f019893d1c498cc3327559d183674 ("audit: Convert int limit
uses to u32"), by converting an int to u32, few conditions will always evaluate
to false.
These warnings were emitted during compilation:
kernel/audit.c: In function ‘audit_set_enabled’:
kernel/audit.c:347:2: warning: comparison of unsigned expression < 0 is always
false [-Wtype-limits]
if (state < AUDIT_OFF || state > AUDIT_LOCKED)
^
kernel/audit.c: In function ‘audit_receive_msg’:
kernel/audit.c:880:9: warning: comparison of unsigned expression < 0 is
always false [-Wtype-limits]
if (s.backlog_wait_time < 0 ||
The following patch removes those unnecessary conditions.
Signed-off-by: Pranith Kumar <bobby.prani(a)gmail.com>
---
kernel/audit.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/kernel/audit.c b/kernel/audit.c
index 72ab759..b1006cb 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -344,7 +344,7 @@ static int audit_set_backlog_wait_time(u32 timeout)
static int audit_set_enabled(u32 state)
{
int rc;
- if (state < AUDIT_OFF || state > AUDIT_LOCKED)
+ if (state > AUDIT_LOCKED)
return -EINVAL;
rc = audit_do_config_change("audit_enabled", &audit_enabled, state);
@@ -877,8 +877,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
if (s.mask & AUDIT_STATUS_BACKLOG_WAIT_TIME) {
if (sizeof(s) > (size_t)nlh->nlmsg_len)
return -EINVAL;
- if (s.backlog_wait_time < 0 ||
- s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME)
+ if (s.backlog_wait_time > 10*AUDIT_BACKLOG_WAIT_TIME)
return -EINVAL;
err = audit_set_backlog_wait_time(s.backlog_wait_time);
if (err < 0)
--
1.9.1
9 years, 7 months
[PATCH 0/2] Update audit syscall classification for execve variants
by David Drysdale
Add a couple of missing execve variants to the syscall
classification code in the audit system.
- Patch 1 is potentially suitable for 3.19 stable.
- Patch 2 need not be back-applied, as audit doesn't yet work
with x32 syscalls in general.
David Drysdale (2):
audit: add execveat to syscall classification
audit,x86: add x32_execve[at] to syscall classification
arch/x86/kernel/audit_64.c | 6 ++++++
lib/compat_audit.c | 3 +++
2 files changed, 9 insertions(+)
--
1.9.1
9 years, 8 months
x32 + audit status?
by David Drysdale
Hi,
Do we currently expect the audit system to work with x32 syscalls?
I was playing with the audit system for the first time today (on
v4.0-rc2, due to [1]), and it didn't seem to work for me. (Tweaking
ptrace.c like the patch below seemed to help, but I may just have
configured something wrong.)
I know there was a bunch of activity around this area in mid-2014,
but I'm not sure what the final position was...
Thanks,
David
[1]: https://lkml.org/lkml/2015/3/4/879
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index e510618b2e91..443932afd9e8 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -1445,7 +1445,7 @@ static void do_audit_syscall_entry(struct
pt_regs *regs, u32 arch)
{
#ifdef CONFIG_X86_64
if (arch == AUDIT_ARCH_X86_64) {
- audit_syscall_entry(regs->orig_ax, regs->di,
+ audit_syscall_entry(regs->orig_ax & __SYSCALL_MASK, regs->di,
regs->si, regs->dx, regs->r10);
} else
#endif
9 years, 8 months
log rendering in real time in audit-viewer
by Xeniya Muratova
Hello Miloslav, and all the guys!
We use audit-viewer for events monitoring.
Unfortunately, if some log is rather big it takes to much time for audit-viewer to parse and render it.
Besides, we need to render log updates in real time, i.e. when a new line appears in a log, it should appear in a viewer too.
Can you suggest the better way to extend audit-viewer to meet these requirements?
Thanks in advance.
Kseniya Muratova,
9 years, 8 months