[PATCH] security: lsm_audit: print pid and tid
by Jeff Vander Stoep
dump_common_audit_data() currently contains a field for pid, but the
value printed is actually the thread ID, tid. Update this value to
return the task group ID. Add a new field for tid. With this change
the values printed by audit now match the values returned by the
getpid() and gettid() syscalls.
Signed-off-by: Jeff Vander Stoep <jeffv(a)google.com>
---
security/lsm_audit.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index cccbf30..57f26c1 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -220,7 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab,
*/
BUILD_BUG_ON(sizeof(a->u) > sizeof(void *)*2);
- audit_log_format(ab, " pid=%d comm=", task_pid_nr(current));
+ audit_log_format(ab, " pid=%d tid=%d comm=", task_tgid_vnr(tsk),
+ task_pid_vnr(tsk));
audit_log_untrustedstring(ab, memcpy(comm, current->comm, sizeof(comm)));
switch (a->type) {
@@ -294,10 +295,12 @@ static void dump_common_audit_data(struct audit_buffer *ab,
case LSM_AUDIT_DATA_TASK: {
struct task_struct *tsk = a->u.tsk;
if (tsk) {
- pid_t pid = task_pid_nr(tsk);
+ pid_t pid = task_tgid_vnr(tsk);
if (pid) {
char comm[sizeof(tsk->comm)];
audit_log_format(ab, " opid=%d ocomm=", pid);
+ audit_log_format(ab, " opid=%d otid=%d ocomm=",
+ pid, task_pid_vnr(tsk));
audit_log_untrustedstring(ab,
memcpy(comm, tsk->comm, sizeof(comm)));
}
--
2.8.0.rc3.226.g39d4020
8 years, 2 months
RHEL-7 and implementing audit rules
by warron.french
Hi, I am back again.
I have some experience and a great deal more comfort with the Linux Audit
configurations nowadays. I learned an aweful lot by working with CentOS-6;
however, this question is focused purely on RHEL-7.
In RHEL-6, audit rules were added directly to */etc/audit/audit.rules*, but
it seems that it is a requirement in RHEL-7 to be placed directly in a file
(any file?) within
*/etc/audit/rules.d/.*
I discovered this by doing some man-page reading of the audit.rules file
after my RHEL-6-variant understanding was turned on its ear. So, I created
an */etc/audit/rules.d/audit.rules* and added my rules in there.
I ensured that I set "-e 1" because the value wasn't already set. I added
a watch rules (-w) and it at first didn't take effect; so then realized, "*this
is RHEL-7, I have to use **systemctl* to restart services."
That also didn't work. I tested with auditctl -l and looked for my new
rules (only 2 of them); so a reboot was committed for something else by a
coworker, and then the *auditctl -l* command actually did display updated
rules. This is very confusing, but I thought nothing more about it,
figuring it is a flaw somewhere.
Anyway, today I added an action rule (-a/Syscall Rule) and it too has not
taken effect; not after a *service auditd restart*, not after a *systemctl
restart auditd.service*, just nothing. I also recently read in a community
post, today, that systemctl doesn't handle the restart of auditd very well
(the comment came from you Mr. Grubb).
I cannot reboot the server yet, and quite frankly I don't want to be forced
to reboot the server everytime I add a rule - it's a lab, not production.
Can someone please tell me what I am doing so wrong, with respect to
handling audit configurations on a RHEL-7 system, and tell me how to work
the processes correctly?
Thanks,
--------------------------
Warron French
8 years, 2 months
[GIT PULL] [PATCH v4 00/26] Delete CURRENT_TIME and CURRENT_TIME_SEC macros
by Deepa Dinamani
The series is aimed at getting rid of CURRENT_TIME and CURRENT_TIME_SEC macros.
The macros are not y2038 safe. There is no plan to transition them into being
y2038 safe.
ktime_get_* api's can be used in their place. And, these are y2038 safe.
Thanks to Arnd Bergmann for all the guidance and discussions.
Patches 2-4 were mostly generated using coccinelle scripts.
All filesystem timestamps use current_fs_time() for right granularity as
mentioned in the respective commit texts of patches. This has a changed
signature, renamed to current_time() and moved to the fs/inode.c.
This series also serves as a preparatory series to transition vfs to 64 bit
timestamps as outlined here: https://lkml.org/lkml/2016/2/12/104 .
As per Linus's suggestion in https://lkml.org/lkml/2016/5/24/663 , all the
inode timestamp changes have been squashed into a single patch. Also,
current_time() now is used as a single generic vfs filesystem timestamp api.
It also takes struct inode* as argument instead of struct super_block*.
Posting all patches together in a bigger series so that the big picture is
clear.
As per the suggestion in https://lwn.net/Articles/672598/, CURRENT_TIME macro
bug fixes are being handled in a series separate from transitioning vfs to
use 64 bit timestamps.
Changes from v3:
* Rebased to 4.8-rc1 to avoid merge conflicts.
* Added CURRENT_TIME deletion and fnic patches back as time64_to_tm() is merged.
* Rearranged a couple of instances of CURRENT_TIME.
Changes from v2:
* Fix buildbot error for uninitialized sb in inode.
* Minor fixes according to Arnd's comments.
* Leave out the fnic and deletion of CURRENT_TIME to be submitted after 4.8 rc1.
Changes from v1:
* Change current_fs_time(struct super_block *) to current_time(struct inode *)
* Note that change to add time64_to_tm() is already part of John's
kernel tree: https://lkml.org/lkml/2016/6/17/875 .
---------------------------------------------------------------
The following changes since commit 09f0834105f7fe315ddaeb77fad15f00565c167e:
Add linux-next specific files for 20160809 (2016-08-09 13:48:00 +1000)
are available in the git repository at:
https://github.com/deepa-hub/vfs current_time-v4.8-rc1
for you to fetch changes up to 050e25f5112626e228b742ed219314abc409a70f:
time: Delete CURRENT_TIME_SEC and CURRENT_TIME (2016-08-13 13:44:41 -0700)
----------------------------------------------------------------
Deepa Dinamani (26):
vfs: Add current_time() api
fs: proc: Delete inode time initializations in proc_alloc_inode()
fs: Replace CURRENT_TIME with current_time() for inode timestamps
fs: Replace CURRENT_TIME_SEC with current_time() for inode timestamps
fs: Replace current_fs_time() with current_time()
fs: ufs: Use ktime_get_real_ts64() for birthtime
fs: jfs: Replace CURRENT_TIME_SEC by current_time()
fs: ext4: Use current_time() for inode timestamps
fs: ubifs: Replace CURRENT_TIME_SEC with current_time
fs: btrfs: Use ktime_get_real_ts for root ctime
fs: udf: Replace CURRENT_TIME with current_time()
fs: cifs: Replace CURRENT_TIME by current_time()
fs: cifs: Replace CURRENT_TIME with ktime_get_real_ts()
fs: cifs: Replace CURRENT_TIME by get_seconds
fs: f2fs: Use ktime_get_real_seconds for sit_info times
drivers: staging: lustre: Replace CURRENT_TIME with current_time()
fs: ocfs2: Use time64_t to represent orphan scan times
fs: ocfs2: Replace CURRENT_TIME macro
audit: Use timespec64 to represent audit timestamps
fs: nfs: Make nfs boot time y2038 safe
block: Replace CURRENT_TIME with ktime_get_real_ts
libceph: Replace CURRENT_TIME with ktime_get_real_ts
fs: ceph: Replace current_fs_time for request stamp
fnic: Use time64_t to represent trace timestamps
time: Delete current_fs_time() function
time: Delete CURRENT_TIME_SEC and CURRENT_TIME
arch/powerpc/platforms/cell/spufs/inode.c | 2 +-
arch/s390/hypfs/inode.c | 4 +--
drivers/block/rbd.c | 2 +-
drivers/char/sonypi.c | 2 +-
drivers/infiniband/hw/qib/qib_fs.c | 2 +-
drivers/misc/ibmasm/ibmasmfs.c | 2 +-
drivers/oprofile/oprofilefs.c | 2 +-
drivers/platform/x86/sony-laptop.c | 2 +-
drivers/scsi/fnic/fnic_trace.c | 4 +--
drivers/scsi/fnic/fnic_trace.h | 2 +-
drivers/staging/lustre/lustre/llite/llite_lib.c | 16 ++++++------
drivers/staging/lustre/lustre/llite/namei.c | 4 +--
drivers/staging/lustre/lustre/mdc/mdc_reint.c | 6 ++---
.../lustre/lustre/obdclass/linux/linux-obdo.c | 6 ++---
drivers/staging/lustre/lustre/obdclass/obdo.c | 6 ++---
drivers/staging/lustre/lustre/osc/osc_io.c | 2 +-
drivers/usb/core/devio.c | 18 +++++++-------
drivers/usb/gadget/function/f_fs.c | 8 +++---
drivers/usb/gadget/legacy/inode.c | 2 +-
fs/9p/vfs_inode.c | 2 +-
fs/adfs/inode.c | 2 +-
fs/affs/amigaffs.c | 6 ++---
fs/affs/inode.c | 2 +-
fs/attr.c | 2 +-
fs/autofs4/inode.c | 2 +-
fs/autofs4/root.c | 6 ++---
fs/bad_inode.c | 2 +-
fs/bfs/dir.c | 14 +++++------
fs/binfmt_misc.c | 2 +-
fs/btrfs/file.c | 6 ++---
fs/btrfs/inode.c | 22 ++++++++--------
fs/btrfs/ioctl.c | 8 +++---
fs/btrfs/root-tree.c | 3 ++-
fs/btrfs/transaction.c | 4 +--
fs/btrfs/xattr.c | 2 +-
fs/ceph/file.c | 4 +--
fs/ceph/inode.c | 2 +-
fs/ceph/mds_client.c | 4 ++-
fs/ceph/xattr.c | 2 +-
fs/cifs/cifsencrypt.c | 4 ++-
fs/cifs/cifssmb.c | 10 ++++----
fs/cifs/file.c | 4 +--
fs/cifs/inode.c | 28 +++++++++++----------
fs/coda/dir.c | 2 +-
fs/coda/file.c | 2 +-
fs/coda/inode.c | 2 +-
fs/configfs/inode.c | 6 ++---
fs/debugfs/inode.c | 2 +-
fs/devpts/inode.c | 6 ++---
fs/efivarfs/inode.c | 2 +-
fs/exofs/dir.c | 6 ++---
fs/exofs/inode.c | 4 +--
fs/exofs/namei.c | 6 ++---
fs/ext2/acl.c | 2 +-
fs/ext2/dir.c | 6 ++---
fs/ext2/ialloc.c | 2 +-
fs/ext2/inode.c | 4 +--
fs/ext2/ioctl.c | 4 +--
fs/ext2/namei.c | 6 ++---
fs/ext2/super.c | 2 +-
fs/ext2/xattr.c | 2 +-
fs/ext4/acl.c | 2 +-
fs/ext4/ext4.h | 6 -----
fs/ext4/extents.c | 10 ++++----
fs/ext4/ialloc.c | 2 +-
fs/ext4/inline.c | 4 +--
fs/ext4/inode.c | 6 ++---
fs/ext4/ioctl.c | 8 +++---
fs/ext4/namei.c | 24 ++++++++++--------
fs/ext4/super.c | 2 +-
fs/ext4/xattr.c | 2 +-
fs/f2fs/dir.c | 8 +++---
fs/f2fs/file.c | 8 +++---
fs/f2fs/inline.c | 2 +-
fs/f2fs/namei.c | 12 ++++-----
fs/f2fs/segment.c | 2 +-
fs/f2fs/segment.h | 5 ++--
fs/f2fs/xattr.c | 2 +-
fs/fat/dir.c | 2 +-
fs/fat/file.c | 6 ++---
fs/fat/inode.c | 2 +-
fs/fat/namei_msdos.c | 12 ++++-----
fs/fat/namei_vfat.c | 10 ++++----
fs/fuse/control.c | 2 +-
fs/fuse/dir.c | 2 +-
fs/gfs2/bmap.c | 8 +++---
fs/gfs2/dir.c | 12 ++++-----
fs/gfs2/inode.c | 8 +++---
fs/gfs2/quota.c | 2 +-
fs/gfs2/xattr.c | 8 +++---
fs/hfs/catalog.c | 8 +++---
fs/hfs/dir.c | 2 +-
fs/hfs/inode.c | 2 +-
fs/hfsplus/catalog.c | 8 +++---
fs/hfsplus/dir.c | 6 ++---
fs/hfsplus/inode.c | 2 +-
fs/hfsplus/ioctl.c | 2 +-
fs/hugetlbfs/inode.c | 10 ++++----
fs/inode.c | 29 +++++++++++++++++++---
fs/jffs2/acl.c | 2 +-
fs/jffs2/fs.c | 2 +-
fs/jfs/acl.c | 2 +-
fs/jfs/inode.c | 2 +-
fs/jfs/ioctl.c | 2 +-
fs/jfs/jfs_inode.c | 2 +-
fs/jfs/namei.c | 24 +++++++++---------
fs/jfs/super.c | 2 +-
fs/jfs/xattr.c | 2 +-
fs/kernfs/inode.c | 2 +-
fs/libfs.c | 14 +++++------
fs/locks.c | 2 +-
fs/logfs/dir.c | 6 ++---
fs/logfs/file.c | 2 +-
fs/logfs/inode.c | 4 +--
fs/logfs/readwrite.c | 4 +--
fs/minix/bitmap.c | 2 +-
fs/minix/dir.c | 6 ++---
fs/minix/itree_common.c | 4 +--
fs/minix/namei.c | 4 +--
fs/nfs/client.c | 2 +-
fs/nfs/netns.h | 2 +-
fs/nfs/nfs4proc.c | 10 +++++---
fs/nfs/nfs4xdr.c | 2 +-
fs/nfsd/blocklayout.c | 2 +-
fs/nilfs2/dir.c | 6 ++---
fs/nilfs2/inode.c | 4 +--
fs/nilfs2/ioctl.c | 2 +-
fs/nilfs2/namei.c | 6 ++---
fs/nsfs.c | 2 +-
fs/ntfs/inode.c | 2 +-
fs/ntfs/mft.c | 2 +-
fs/ocfs2/acl.c | 2 +-
fs/ocfs2/alloc.c | 2 +-
fs/ocfs2/aops.c | 2 +-
fs/ocfs2/cluster/heartbeat.c | 2 +-
fs/ocfs2/dir.c | 4 +--
fs/ocfs2/dlmfs/dlmfs.c | 4 +--
fs/ocfs2/file.c | 12 ++++-----
fs/ocfs2/inode.c | 2 +-
fs/ocfs2/journal.c | 4 +--
fs/ocfs2/move_extents.c | 2 +-
fs/ocfs2/namei.c | 16 ++++++------
fs/ocfs2/ocfs2.h | 2 +-
fs/ocfs2/refcounttree.c | 4 +--
fs/ocfs2/super.c | 2 +-
fs/ocfs2/xattr.c | 2 +-
fs/omfs/dir.c | 4 +--
fs/omfs/inode.c | 2 +-
fs/openpromfs/inode.c | 2 +-
fs/orangefs/file.c | 2 +-
fs/orangefs/inode.c | 2 +-
fs/orangefs/namei.c | 10 ++++----
fs/pipe.c | 2 +-
fs/posix_acl.c | 2 +-
fs/proc/base.c | 2 +-
fs/proc/inode.c | 3 +--
fs/proc/proc_sysctl.c | 2 +-
fs/proc/self.c | 2 +-
fs/proc/thread_self.c | 2 +-
fs/pstore/inode.c | 2 +-
fs/ramfs/inode.c | 6 ++---
fs/reiserfs/inode.c | 2 +-
fs/reiserfs/ioctl.c | 4 +--
fs/reiserfs/namei.c | 12 ++++-----
fs/reiserfs/stree.c | 8 +++---
fs/reiserfs/super.c | 2 +-
fs/reiserfs/xattr.c | 6 ++---
fs/reiserfs/xattr_acl.c | 2 +-
fs/sysv/dir.c | 6 ++---
fs/sysv/ialloc.c | 2 +-
fs/sysv/itree.c | 4 +--
fs/sysv/namei.c | 4 +--
fs/tracefs/inode.c | 2 +-
fs/ubifs/dir.c | 10 ++++----
fs/ubifs/file.c | 12 ++++-----
fs/ubifs/ioctl.c | 2 +-
fs/ubifs/misc.h | 10 --------
fs/ubifs/sb.c | 14 ++++++++---
fs/ubifs/xattr.c | 6 ++---
fs/udf/ialloc.c | 2 +-
fs/udf/inode.c | 4 +--
fs/udf/namei.c | 20 +++++++--------
fs/udf/super.c | 9 ++++---
fs/ufs/dir.c | 6 ++---
fs/ufs/ialloc.c | 8 +++---
fs/ufs/inode.c | 6 ++---
fs/ufs/namei.c | 6 ++---
fs/xfs/xfs_acl.c | 2 +-
fs/xfs/xfs_inode.c | 2 +-
fs/xfs/xfs_iops.c | 2 +-
fs/xfs/xfs_trans_inode.c | 2 +-
include/linux/audit.h | 4 +--
include/linux/fs.h | 2 +-
include/linux/time.h | 3 ---
ipc/mqueue.c | 18 +++++++-------
kernel/audit.c | 10 ++++----
kernel/audit.h | 2 +-
kernel/auditsc.c | 6 ++---
kernel/bpf/inode.c | 2 +-
kernel/time/time.c | 14 -----------
mm/shmem.c | 20 +++++++--------
net/ceph/messenger.c | 6 +++--
net/ceph/osd_client.c | 4 +--
net/sunrpc/rpc_pipe.c | 2 +-
security/apparmor/apparmorfs.c | 2 +-
security/inode.c | 2 +-
security/selinux/selinuxfs.c | 2 +-
207 files changed, 540 insertions(+), 524 deletions(-)
--
1.9.1
Cc: adilger.kernel(a)dilger.ca
Cc: adrian.hunter(a)intel.com
Cc: anna.schumaker(a)netapp.com
Cc: buchino(a)cisco.com
Cc: ceph-devel(a)vger.kernel.org
Cc: clm(a)fb.com
Cc: cm224.lee(a)samsung.com
Cc: dedekind1(a)gmail.com
Cc: dsterba(a)suse.com
Cc: dushistov(a)mail.ru
Cc: elder(a)kernel.org
Cc: eparis(a)redhat.com
Cc: gregkh(a)linuxfoundation.org
Cc: hiralpat(a)cisco.com
Cc: idryomov(a)gmail.com
Cc: jack(a)suse.com
Cc: jaegeuk(a)kernel.org
Cc: jbacik(a)fb.com
Cc: jejb(a)linux.vnet.ibm.com
Cc: jfs-discussion(a)lists.sourceforge.net
Cc: jlbec(a)evilplan.org
Cc: john.stultz(a)linaro.org
Cc: linux-audit(a)redhat.com
Cc: linux-btrfs(a)vger.kernel.org
Cc: linux-ext4(a)vger.kernel.org
Cc: linux-f2fs-devel(a)lists.sourceforge.net
Cc: linux-mtd(a)lists.infradead.org
Cc: linux-nfs(a)vger.kernel.org
Cc: linux-scsi(a)vger.kernel.org
Cc: lustre-devel(a)lists.lustre.org
Cc: martin.petersen(a)oracle.com
Cc: mfasheh(a)suse.com
Cc: ocfs2-devel(a)oss.oracle.com
Cc: paul(a)paul-moore.com
Cc: sage(a)redhat.com
Cc: sfrench(a)samba.org
Cc: shaggy(a)kernel.org
Cc: sramars(a)cisco.com
Cc: trond.myklebust(a)primarydata.com
Cc: zyan(a)redhat.com
8 years, 2 months
[PATCH 0/2] introduce get_task_exe_file and use it to fix audit_exe_compare
by Mateusz Guzik
audit_exe_compare directly accesses mm->exe_file without making sure the
object is stable. Fixing it using current primitives results in
partially duplicating what proc_exe_link is doing.
As such, introduce a trivial helper which can be used in both places and
fix the func.
Mateusz Guzik (2):
mm: introduce get_task_exe_file
audit: fix exe_file access in audit_exe_compare
fs/proc/base.c | 7 +------
include/linux/mm.h | 1 +
kernel/audit_watch.c | 8 +++++---
kernel/fork.c | 24 ++++++++++++++++++++++++
4 files changed, 31 insertions(+), 9 deletions(-)
--
1.8.3.1
8 years, 2 months
[PATCH] audit: fix audit_exe_compare using get_mm_exe_file
by Richard Guy Briggs
Fix original naive attempt to get/lock access to task->mm->exe_file by
using get_mm_exe_file and checking for NULL.
See: https://lkml.org/lkml/2016/7/30/97
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
kernel/audit_watch.c | 13 ++++++++++---
1 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c
index d6709eb..0b29279 100644
--- a/kernel/audit_watch.c
+++ b/kernel/audit_watch.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/file.h>
#include <linux/kernel.h>
#include <linux/audit.h>
#include <linux/kthread.h>
@@ -540,14 +541,20 @@ int audit_dupe_exe(struct audit_krule *new, struct audit_krule *old)
int audit_exe_compare(struct task_struct *tsk, struct audit_fsnotify_mark *mark)
{
+ struct mm_struct *mm;
struct file *exe_file;
unsigned long ino;
dev_t dev;
- rcu_read_lock();
- exe_file = rcu_dereference(tsk->mm->exe_file);
+ mm = get_task_mm(tsk);
+ if (!mm)
+ return 0;
+ exe_file = get_mm_exe_file(mm);
+ mmput(mm);
+ if (!exe_file)
+ return 0;
ino = exe_file->f_inode->i_ino;
dev = exe_file->f_inode->i_sb->s_dev;
- rcu_read_unlock();
+ fput(exe_file);
return audit_mark_compare(mark, ino, dev);
}
--
1.7.1
8 years, 2 months
Re: [PATCH] prctl: remove one-shot limitation for changing exe link
by Eric W. Biederman
Mateusz Guzik <mguzik(a)redhat.com> writes:
> On Sat, Jul 30, 2016 at 12:31:40PM -0500, Eric W. Biederman wrote:
>> So what I am requesting is very simple. That the checks in
>> prctl_set_mm_exe_file be tightened up to more closely approach what
>> execve requires. Thus preserving the value of the /proc/[pid]/exe for
>> the applications that want to use the exe link.
>>
>> Once the checks in prctl_set_mm_exe_file are tightened up please feel
>> free to remove the one shot test.
>>
>
> This is more fishy.
>
> First of all exe_file is used by the audit subsystem. So someone has to
> ask audit people what is the significance (if any) of the field.
>
> All exe_file users but one use get_mm_exe_file and handle NULL
> gracefully.
>
> Even with the current limit of changing the field once, the user can
> cause a transient failure of get_mm_exe_file which can fail to increment
> the refcount before it drops to 0.
>
> This transient failure can be used to get a NULL value stored in
> ->exe_file during fork (in dup_mmap):
> RCU_INIT_POINTER(mm->exe_file, get_mm_exe_file(oldmm));
>
> The one place which is not using get_mm_exe_file to get to the pointer
> is audit_exe_compare:
> rcu_read_lock();
> exe_file = rcu_dereference(tsk->mm->exe_file);
> ino = exe_file->f_inode->i_ino;
> dev = exe_file->f_inode->i_sb->s_dev;
> rcu_read_unlock();
>
> This is buggy on 2 accounts:
> 1. exe_file can be NULL
> 2. rcu does not protect f_inode
>
> The issue is made worse with allowing arbitrary number changes.
>
> Modifying get_mm_exe_file to retry is trivial and in effect never return
> NULL is trivial. With arbitrary number of changes allowed this may
> require some cond_resched() or something.
>
> For comments I cc'ed Richard Guy Briggs, who is both an audit person and
> the author of audit_exe_compare.
That is fair. Keeping the existing users working is what needs to
happen.
At the same time we have an arbitrary number of possible changes with
exec, but I guess that works differently because the mm is changed as
well.
So yes let's bug fix this piece of code and then we can see about
relaxing constraints.
Eric
8 years, 2 months
[PATCH] semanage: add auditing of changes in records
by Miroslav Vadkerti
Common Criteria requirement FMT_MSA.1 needs any configuration change
that affect enforcement of policy to be audited. This patch adds
auditing of changes in security context mappings for network ports,
interfaces, nodes and file contexts.
A new function log_change is introduced that audits additions,
modification and removal of the mappings via the USER_MAC_CONFIG_CHANGE
audit event.
The format of the audit events was discussed with the audit userspace
maintainer.
This patch resolves: https://bugzilla.redhat.com/show_bug.cgi?id=829175
Signed-off-by: Miroslav Vadkerti <mvadkert(a)redhat.com>
---
policycoreutils/semanage/seobject.py | 75 ++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py
index 3b0b108..7d6caa3 100644
--- a/policycoreutils/semanage/seobject.py
+++ b/policycoreutils/semanage/seobject.py
@@ -82,6 +82,21 @@ file_type_str_to_option = {"all files": "a",
"socket file": "s",
"symbolic link": "l",
"named pipe": "p"}
+
+proto_to_audit = {"tcp": 17,
+ "udp": 6,
+ "ipv4": 4,
+ "ipv6": 41}
+
+ftype_to_audit = {"": "any",
+ "b": "block",
+ "c": "char",
+ "d": "dir",
+ "f": "file",
+ "l": "symlink",
+ "p": "pipe",
+ "s": "socket"}
+
try:
import audit
@@ -90,6 +105,7 @@ try:
def __init__(self):
self.audit_fd = audit.audit_open()
self.log_list = []
+ self.log_change_list = []
def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
@@ -109,10 +125,17 @@ try:
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
+ def log_change(self, msg):
+ self.log_change_list.append([self.audit_fd, audit.AUDIT_USER_MAC_CONFIG_CHANGE, str(msg), "semanage", "", "", ""])
+
def commit(self, success):
for l in self.log_list:
audit.audit_log_semanage_message(*(l + [success]))
+ for l in self.log_change_list:
+ audit.audit_log_user_comm_message(*(l + [success]))
+
self.log_list = []
+ self.log_change_list = []
except:
class logger:
@@ -138,6 +161,9 @@ except:
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
+ def log_change(self, msg):
+ self.log_list.append(" %s" % msg)
+
def commit(self, success):
if success == 1:
message = "Successful: "
@@ -155,6 +181,9 @@ class nulllogger:
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
pass
+ def log_change(self, msg):
+ pass
+
def commit(self, success):
pass
@@ -1109,6 +1138,8 @@ class portRecords(semanageRecords):
semanage_port_key_free(k)
semanage_port_free(p)
+ self.mylog.log_change("resrc=port op=add lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, proto_to_audit[proto], "system_u", "object_r", type, serange))
+
def add(self, port, proto, serange, type):
self.begin()
self.__add(port, proto, serange, type)
@@ -1150,6 +1181,8 @@ class portRecords(semanageRecords):
semanage_port_key_free(k)
semanage_port_free(p)
+ self.mylog.log_change("resrc=port op=modify lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, proto_to_audit[proto], "system_u", "object_r", setype, serange))
+
def modify(self, port, proto, serange, setype):
self.begin()
self.__modify(port, proto, serange, setype)
@@ -1168,6 +1201,7 @@ class portRecords(semanageRecords):
low = semanage_port_get_low(port)
high = semanage_port_get_high(port)
port_str = "%s-%s" % (low, high)
+
(k, proto_d, low, high) = self.__genkey(port_str, proto_str)
if rc < 0:
raise ValueError(_("Could not create a key for %s") % port_str)
@@ -1177,6 +1211,11 @@ class portRecords(semanageRecords):
raise ValueError(_("Could not delete the port %s") % port_str)
semanage_port_key_free(k)
+ if low == high:
+ port_str = low
+
+ self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port_str, proto_to_audit[proto_str]))
+
self.commit()
def __delete(self, port, proto):
@@ -1199,6 +1238,8 @@ class portRecords(semanageRecords):
semanage_port_key_free(k)
+ self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port, proto_to_audit[proto]))
+
def delete(self, port, proto):
self.begin()
self.__delete(port, proto)
@@ -1380,6 +1421,8 @@ class nodeRecords(semanageRecords):
semanage_node_key_free(k)
semanage_node_free(node)
+ self.mylog.log_change("resrc=node op=add laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, proto_to_audit[self.protocol[proto]], "system_u", "object_r", ctype, serange))
+
def add(self, addr, mask, proto, serange, ctype):
self.begin()
self.__add(addr, mask, proto, serange, ctype)
@@ -1421,6 +1464,8 @@ class nodeRecords(semanageRecords):
semanage_node_key_free(k)
semanage_node_free(node)
+ self.mylog.log_change("resrc=node op=modify laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, proto_to_audit[self.protocol[proto]], "system_u", "object_r", setype, serange))
+
def modify(self, addr, mask, proto, serange, setype):
self.begin()
self.__modify(addr, mask, proto, serange, setype)
@@ -1452,6 +1497,8 @@ class nodeRecords(semanageRecords):
semanage_node_key_free(k)
+ self.mylog.log_change("resrc=node op=delete laddr=%s netmask=%s proto=%s" % (addr, mask, proto_to_audit[self.protocol[proto]]))
+
def delete(self, addr, mask, proto):
self.begin()
self.__delete(addr, mask, proto)
@@ -1581,6 +1628,8 @@ class interfaceRecords(semanageRecords):
semanage_iface_key_free(k)
semanage_iface_free(iface)
+ self.mylog.log_change("resrc=interface op=add netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", ctype, serange))
+
def add(self, interface, serange, ctype):
self.begin()
self.__add(interface, serange, ctype)
@@ -1618,6 +1667,8 @@ class interfaceRecords(semanageRecords):
semanage_iface_key_free(k)
semanage_iface_free(iface)
+ self.mylog.log_change("resrc=interface op=modify netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", setype, serange))
+
def modify(self, interface, serange, setype):
self.begin()
self.__modify(interface, serange, setype)
@@ -1646,6 +1697,8 @@ class interfaceRecords(semanageRecords):
semanage_iface_key_free(k)
+ self.mylog.log_change("resrc=interface op=delete netif=%s" % interface)
+
def delete(self, interface):
self.begin()
self.__delete(interface)
@@ -1775,6 +1828,8 @@ class fcontextRecords(semanageRecords):
if i.startswith(target + "/"):
raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i]))
+ self.mylog.log_change("resrc=fcontext op=add-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0)))
+
self.equiv[target] = substitute
self.equal_ind = True
self.commit()
@@ -1785,6 +1840,9 @@ class fcontextRecords(semanageRecords):
raise ValueError(_("Equivalence class for %s does not exists") % target)
self.equiv[target] = substitute
self.equal_ind = True
+
+ self.mylog.log_change("resrc=fcontext op=modify-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0)))
+
self.commit()
def createcon(self, target, seuser="system_u"):
@@ -1879,6 +1937,11 @@ class fcontextRecords(semanageRecords):
semanage_fcontext_key_free(k)
semanage_fcontext_free(fcontext)
+ if not seuser:
+ seuser = "system_u"
+
+ self.mylog.log_change("resrc=fcontext op=add %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", type, serange))
+
def add(self, target, type, ftype="", serange="", seuser="system_u"):
self.begin()
self.__add(target, type, ftype, serange, seuser)
@@ -1939,6 +2002,11 @@ class fcontextRecords(semanageRecords):
semanage_fcontext_key_free(k)
semanage_fcontext_free(fcontext)
+ if not seuser:
+ seuser = "system_u"
+
+ self.mylog.log_change("resrc=fcontext op=modify %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", type, serange))
+
def modify(self, target, setype, ftype, serange, seuser):
self.begin()
self.__modify(target, setype, ftype, serange, seuser)
@@ -1964,6 +2032,8 @@ class fcontextRecords(semanageRecords):
raise ValueError(_("Could not delete the file context %s") % target)
semanage_fcontext_key_free(k)
+ self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype_str]))
+
self.equiv = {}
self.equal_ind = True
self.commit()
@@ -1972,6 +2042,9 @@ class fcontextRecords(semanageRecords):
if target in self.equiv.keys():
self.equiv.pop(target)
self.equal_ind = True
+
+ self.mylog.log_change("resrc=fcontext op=delete-equal %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype]))
+
return
(rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
@@ -1996,6 +2069,8 @@ class fcontextRecords(semanageRecords):
semanage_fcontext_key_free(k)
+ self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype]))
+
def delete(self, target, ftype):
self.begin()
self.__delete(target, ftype)
--
1.8.3.1
8 years, 2 months
[PATCH 1/2] semanage: add auditing of changes in records
by Miroslav Vadkerti
Common Criteria requirement FMT_MSA.1 needs any configuration change
that affect enforcement of policy to be audited. This patch adds
auditing of changes in security context mappings for network ports,
interfaces, nodes and file contexts.
A new function log_change is introduced that audits additions,
modification and removal of the mappings via the USER_MAC_CONFIG_CHANGE
audit event.
The format of the audit events was discussed with the audit userspace
maintainer.
This patch resolves: https://bugzilla.redhat.com/show_bug.cgi?id=829175
Signed-off-by: Miroslav Vadkerti <mvadkert(a)redhat.com>
---
policycoreutils/semanage/seobject.py | 75 ++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+)
diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py
index 3b0b108..799ce24 100644
--- a/policycoreutils/semanage/seobject.py
+++ b/policycoreutils/semanage/seobject.py
@@ -82,6 +82,21 @@ file_type_str_to_option = {"all files": "a",
"socket file": "s",
"symbolic link": "l",
"named pipe": "p"}
+
+proto_to_audit = {"tcp": 17,
+ "udp": 6,
+ "ipv4": 4,
+ "ipv6": 41}
+
+ftype_to_audit = {"": "any",
+ "b": "block",
+ "c": "char",
+ "d": "dir",
+ "f": "file",
+ "l": "symlink",
+ "p": "pipe",
+ "s": "socket"}
+
try:
import audit
@@ -90,6 +105,7 @@ try:
def __init__(self):
self.audit_fd = audit.audit_open()
self.log_list = []
+ self.log_change_list = []
def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
@@ -109,10 +125,17 @@ try:
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
+ def log_change(self, msg, hostname="", addr="", tty=""):
+ self.log_change_list.append([self.audit_fd, audit.AUDIT_USER_MAC_CONFIG_CHANGE, str(msg), "semanage", hostname, addr, tty])
+
def commit(self, success):
for l in self.log_list:
audit.audit_log_semanage_message(*(l + [success]))
+ for l in self.log_change_list:
+ audit.audit_log_user_comm_message(*(l + [success]))
+
self.log_list = []
+ self.log_change_list = []
except:
class logger:
@@ -138,6 +161,9 @@ except:
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
+ def log_change(self, msg, hostname="", addr="", tty=""):
+ self.log_list.append(" %s" % msg)
+
def commit(self, success):
if success == 1:
message = "Successful: "
@@ -155,6 +181,9 @@ class nulllogger:
def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
pass
+ def log_change(self, msg, hostname="", addr="", tty=""):
+ pass
+
def commit(self, success):
pass
@@ -1109,6 +1138,8 @@ class portRecords(semanageRecords):
semanage_port_key_free(k)
semanage_port_free(p)
+ self.mylog.log_change("resrc=port op=add lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, proto_to_audit[proto], "system_u", "object_r", type, serange))
+
def add(self, port, proto, serange, type):
self.begin()
self.__add(port, proto, serange, type)
@@ -1150,6 +1181,8 @@ class portRecords(semanageRecords):
semanage_port_key_free(k)
semanage_port_free(p)
+ self.mylog.log_change("resrc=port op=modify lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, proto_to_audit[proto], "system_u", "object_r", setype, serange))
+
def modify(self, port, proto, serange, setype):
self.begin()
self.__modify(port, proto, serange, setype)
@@ -1168,6 +1201,7 @@ class portRecords(semanageRecords):
low = semanage_port_get_low(port)
high = semanage_port_get_high(port)
port_str = "%s-%s" % (low, high)
+
(k, proto_d, low, high) = self.__genkey(port_str, proto_str)
if rc < 0:
raise ValueError(_("Could not create a key for %s") % port_str)
@@ -1177,6 +1211,11 @@ class portRecords(semanageRecords):
raise ValueError(_("Could not delete the port %s") % port_str)
semanage_port_key_free(k)
+ if low == high:
+ port_str = low
+
+ self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port_str, proto_to_audit[proto_str]))
+
self.commit()
def __delete(self, port, proto):
@@ -1199,6 +1238,8 @@ class portRecords(semanageRecords):
semanage_port_key_free(k)
+ self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port, proto_to_audit[proto]))
+
def delete(self, port, proto):
self.begin()
self.__delete(port, proto)
@@ -1380,6 +1421,8 @@ class nodeRecords(semanageRecords):
semanage_node_key_free(k)
semanage_node_free(node)
+ self.mylog.log_change("resrc=node op=add laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, proto_to_audit[self.protocol[proto]], "system_u", "object_r", ctype, serange))
+
def add(self, addr, mask, proto, serange, ctype):
self.begin()
self.__add(addr, mask, proto, serange, ctype)
@@ -1421,6 +1464,8 @@ class nodeRecords(semanageRecords):
semanage_node_key_free(k)
semanage_node_free(node)
+ self.mylog.log_change("resrc=node op=modify laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, proto_to_audit[self.protocol[proto]], "system_u", "object_r", setype, serange))
+
def modify(self, addr, mask, proto, serange, setype):
self.begin()
self.__modify(addr, mask, proto, serange, setype)
@@ -1452,6 +1497,8 @@ class nodeRecords(semanageRecords):
semanage_node_key_free(k)
+ self.mylog.log_change("resrc=node op=delete laddr=%s netmask=%s proto=%s" % (addr, mask, proto_to_audit[self.protocol[proto]]))
+
def delete(self, addr, mask, proto):
self.begin()
self.__delete(addr, mask, proto)
@@ -1581,6 +1628,8 @@ class interfaceRecords(semanageRecords):
semanage_iface_key_free(k)
semanage_iface_free(iface)
+ self.mylog.log_change("resrc=interface op=add netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", ctype, serange))
+
def add(self, interface, serange, ctype):
self.begin()
self.__add(interface, serange, ctype)
@@ -1618,6 +1667,8 @@ class interfaceRecords(semanageRecords):
semanage_iface_key_free(k)
semanage_iface_free(iface)
+ self.mylog.log_change("resrc=interface op=modify netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", setype, serange))
+
def modify(self, interface, serange, setype):
self.begin()
self.__modify(interface, serange, setype)
@@ -1646,6 +1697,8 @@ class interfaceRecords(semanageRecords):
semanage_iface_key_free(k)
+ self.mylog.log_change("resrc=interface op=delete netif=%s" % interface)
+
def delete(self, interface):
self.begin()
self.__delete(interface)
@@ -1775,6 +1828,8 @@ class fcontextRecords(semanageRecords):
if i.startswith(target + "/"):
raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i]))
+ self.mylog.log_change("resrc=fcontext op=add-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0)))
+
self.equiv[target] = substitute
self.equal_ind = True
self.commit()
@@ -1785,6 +1840,9 @@ class fcontextRecords(semanageRecords):
raise ValueError(_("Equivalence class for %s does not exists") % target)
self.equiv[target] = substitute
self.equal_ind = True
+
+ self.mylog.log_change("resrc=fcontext op=modify-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0)))
+
self.commit()
def createcon(self, target, seuser="system_u"):
@@ -1879,6 +1937,11 @@ class fcontextRecords(semanageRecords):
semanage_fcontext_key_free(k)
semanage_fcontext_free(fcontext)
+ if not seuser:
+ seuser = "system_u"
+
+ self.mylog.log_change("resrc=fcontext op=add %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", type, serange))
+
def add(self, target, type, ftype="", serange="", seuser="system_u"):
self.begin()
self.__add(target, type, ftype, serange, seuser)
@@ -1939,6 +2002,11 @@ class fcontextRecords(semanageRecords):
semanage_fcontext_key_free(k)
semanage_fcontext_free(fcontext)
+ if not seuser:
+ seuser = "system_u"
+
+ self.mylog.log_change("resrc=fcontext op=modify %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", type, serange))
+
def modify(self, target, setype, ftype, serange, seuser):
self.begin()
self.__modify(target, setype, ftype, serange, seuser)
@@ -1964,6 +2032,8 @@ class fcontextRecords(semanageRecords):
raise ValueError(_("Could not delete the file context %s") % target)
semanage_fcontext_key_free(k)
+ self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype_str]))
+
self.equiv = {}
self.equal_ind = True
self.commit()
@@ -1972,6 +2042,9 @@ class fcontextRecords(semanageRecords):
if target in self.equiv.keys():
self.equiv.pop(target)
self.equal_ind = True
+
+ self.mylog.log_change("resrc=fcontext op=delete-equal %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype]))
+
return
(rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
@@ -1996,6 +2069,8 @@ class fcontextRecords(semanageRecords):
semanage_fcontext_key_free(k)
+ self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype]))
+
def delete(self, target, ftype):
self.begin()
self.__delete(target, ftype)
--
1.8.3.1
8 years, 2 months