[PATCH] Process Events Connector
This patch adds a connector that reports fork, exec, id change, and exit events for all processes to userspace. It replaces the fork_advisor patch that ELSA is currently using. Applications that may find these events useful include accounting/auditing (e.g. ELSA), system activity monitoring (e.g. top), security, and resource management (e.g. CKRM). Signed-off-by: Matt Helsley <matthltc@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
49364ce253
commit
9f46080c41
9 changed files with 379 additions and 0 deletions
|
@ -10,4 +10,12 @@ config CONNECTOR
|
||||||
Connector support can also be built as a module. If so, the module
|
Connector support can also be built as a module. If so, the module
|
||||||
will be called cn.ko.
|
will be called cn.ko.
|
||||||
|
|
||||||
|
config PROC_EVENTS
|
||||||
|
boolean "Report process events to userspace"
|
||||||
|
depends on CONNECTOR=y
|
||||||
|
default y
|
||||||
|
---help---
|
||||||
|
Provide a connector that reports process events to userspace. Send
|
||||||
|
events such as fork, exec, id change (uid, gid, suid, etc), and exit.
|
||||||
|
|
||||||
endmenu
|
endmenu
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
obj-$(CONFIG_CONNECTOR) += cn.o
|
obj-$(CONFIG_CONNECTOR) += cn.o
|
||||||
|
obj-$(CONFIG_PROC_EVENTS) += cn_proc.o
|
||||||
|
|
||||||
cn-y += cn_queue.o connector.o
|
cn-y += cn_queue.o connector.o
|
||||||
|
|
222
drivers/connector/cn_proc.c
Normal file
222
drivers/connector/cn_proc.c
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
/*
|
||||||
|
* cn_proc.c - process events connector
|
||||||
|
*
|
||||||
|
* Copyright (C) Matt Helsley, IBM Corp. 2005
|
||||||
|
* Based on cn_fork.c by Guillaume Thouvenin <guillaume.thouvenin@bull.net>
|
||||||
|
* Original copyright notice follows:
|
||||||
|
* Copyright (C) 2005 BULL SA.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <asm/atomic.h>
|
||||||
|
|
||||||
|
#include <linux/cn_proc.h>
|
||||||
|
|
||||||
|
#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
|
||||||
|
|
||||||
|
static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
|
||||||
|
static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
|
||||||
|
|
||||||
|
/* proc_counts is used as the sequence number of the netlink message */
|
||||||
|
static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
|
||||||
|
|
||||||
|
static inline void get_seq(__u32 *ts, int *cpu)
|
||||||
|
{
|
||||||
|
*ts = get_cpu_var(proc_event_counts)++;
|
||||||
|
*cpu = smp_processor_id();
|
||||||
|
put_cpu_var(proc_counts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_fork_connector(struct task_struct *task)
|
||||||
|
{
|
||||||
|
struct cn_msg *msg;
|
||||||
|
struct proc_event *ev;
|
||||||
|
__u8 buffer[CN_PROC_MSG_SIZE];
|
||||||
|
|
||||||
|
if (atomic_read(&proc_event_num_listeners) < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
msg = (struct cn_msg*)buffer;
|
||||||
|
ev = (struct proc_event*)msg->data;
|
||||||
|
get_seq(&msg->seq, &ev->cpu);
|
||||||
|
ev->what = PROC_EVENT_FORK;
|
||||||
|
ev->event_data.fork.parent_pid = task->real_parent->pid;
|
||||||
|
ev->event_data.fork.parent_tgid = task->real_parent->tgid;
|
||||||
|
ev->event_data.fork.child_pid = task->pid;
|
||||||
|
ev->event_data.fork.child_tgid = task->tgid;
|
||||||
|
|
||||||
|
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
|
||||||
|
msg->ack = 0; /* not used */
|
||||||
|
msg->len = sizeof(*ev);
|
||||||
|
/* If cn_netlink_send() failed, the data is not sent */
|
||||||
|
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_exec_connector(struct task_struct *task)
|
||||||
|
{
|
||||||
|
struct cn_msg *msg;
|
||||||
|
struct proc_event *ev;
|
||||||
|
__u8 buffer[CN_PROC_MSG_SIZE];
|
||||||
|
|
||||||
|
if (atomic_read(&proc_event_num_listeners) < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
msg = (struct cn_msg*)buffer;
|
||||||
|
ev = (struct proc_event*)msg->data;
|
||||||
|
get_seq(&msg->seq, &ev->cpu);
|
||||||
|
ev->what = PROC_EVENT_EXEC;
|
||||||
|
ev->event_data.exec.process_pid = task->pid;
|
||||||
|
ev->event_data.exec.process_tgid = task->tgid;
|
||||||
|
|
||||||
|
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
|
||||||
|
msg->ack = 0; /* not used */
|
||||||
|
msg->len = sizeof(*ev);
|
||||||
|
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_id_connector(struct task_struct *task, int which_id)
|
||||||
|
{
|
||||||
|
struct cn_msg *msg;
|
||||||
|
struct proc_event *ev;
|
||||||
|
__u8 buffer[CN_PROC_MSG_SIZE];
|
||||||
|
|
||||||
|
if (atomic_read(&proc_event_num_listeners) < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
msg = (struct cn_msg*)buffer;
|
||||||
|
ev = (struct proc_event*)msg->data;
|
||||||
|
ev->what = which_id;
|
||||||
|
ev->event_data.id.process_pid = task->pid;
|
||||||
|
ev->event_data.id.process_tgid = task->tgid;
|
||||||
|
if (which_id == PROC_EVENT_UID) {
|
||||||
|
ev->event_data.id.r.ruid = task->uid;
|
||||||
|
ev->event_data.id.e.euid = task->euid;
|
||||||
|
} else if (which_id == PROC_EVENT_GID) {
|
||||||
|
ev->event_data.id.r.rgid = task->gid;
|
||||||
|
ev->event_data.id.e.egid = task->egid;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
get_seq(&msg->seq, &ev->cpu);
|
||||||
|
|
||||||
|
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
|
||||||
|
msg->ack = 0; /* not used */
|
||||||
|
msg->len = sizeof(*ev);
|
||||||
|
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void proc_exit_connector(struct task_struct *task)
|
||||||
|
{
|
||||||
|
struct cn_msg *msg;
|
||||||
|
struct proc_event *ev;
|
||||||
|
__u8 buffer[CN_PROC_MSG_SIZE];
|
||||||
|
|
||||||
|
if (atomic_read(&proc_event_num_listeners) < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
msg = (struct cn_msg*)buffer;
|
||||||
|
ev = (struct proc_event*)msg->data;
|
||||||
|
get_seq(&msg->seq, &ev->cpu);
|
||||||
|
ev->what = PROC_EVENT_EXIT;
|
||||||
|
ev->event_data.exit.process_pid = task->pid;
|
||||||
|
ev->event_data.exit.process_tgid = task->tgid;
|
||||||
|
ev->event_data.exit.exit_code = task->exit_code;
|
||||||
|
ev->event_data.exit.exit_signal = task->exit_signal;
|
||||||
|
|
||||||
|
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
|
||||||
|
msg->ack = 0; /* not used */
|
||||||
|
msg->len = sizeof(*ev);
|
||||||
|
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send an acknowledgement message to userspace
|
||||||
|
*
|
||||||
|
* Use 0 for success, EFOO otherwise.
|
||||||
|
* Note: this is the negative of conventional kernel error
|
||||||
|
* values because it's not being returned via syscall return
|
||||||
|
* mechanisms.
|
||||||
|
*/
|
||||||
|
static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
|
||||||
|
{
|
||||||
|
struct cn_msg *msg;
|
||||||
|
struct proc_event *ev;
|
||||||
|
__u8 buffer[CN_PROC_MSG_SIZE];
|
||||||
|
|
||||||
|
if (atomic_read(&proc_event_num_listeners) < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
msg = (struct cn_msg*)buffer;
|
||||||
|
ev = (struct proc_event*)msg->data;
|
||||||
|
msg->seq = rcvd_seq;
|
||||||
|
ev->cpu = -1;
|
||||||
|
ev->what = PROC_EVENT_NONE;
|
||||||
|
ev->event_data.ack.err = err;
|
||||||
|
memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
|
||||||
|
msg->ack = rcvd_ack + 1;
|
||||||
|
msg->len = sizeof(*ev);
|
||||||
|
cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cn_proc_mcast_ctl
|
||||||
|
* @data: message sent from userspace via the connector
|
||||||
|
*/
|
||||||
|
static void cn_proc_mcast_ctl(void *data)
|
||||||
|
{
|
||||||
|
struct cn_msg *msg = data;
|
||||||
|
enum proc_cn_mcast_op *mc_op = NULL;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (msg->len != sizeof(*mc_op))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mc_op = (enum proc_cn_mcast_op*)msg->data;
|
||||||
|
switch (*mc_op) {
|
||||||
|
case PROC_CN_MCAST_LISTEN:
|
||||||
|
atomic_inc(&proc_event_num_listeners);
|
||||||
|
break;
|
||||||
|
case PROC_CN_MCAST_IGNORE:
|
||||||
|
atomic_dec(&proc_event_num_listeners);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cn_proc_ack(err, msg->seq, msg->ack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cn_proc_init - initialization entry point
|
||||||
|
*
|
||||||
|
* Adds the connector callback to the connector driver.
|
||||||
|
*/
|
||||||
|
static int __init cn_proc_init(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if ((err = cn_add_callback(&cn_proc_event_id, "cn_proc",
|
||||||
|
&cn_proc_mcast_ctl))) {
|
||||||
|
printk(KERN_WARNING "cn_proc failed to register\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(cn_proc_init);
|
|
@ -48,6 +48,7 @@
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/rmap.h>
|
#include <linux/rmap.h>
|
||||||
#include <linux/acct.h>
|
#include <linux/acct.h>
|
||||||
|
#include <linux/cn_proc.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/mmu_context.h>
|
#include <asm/mmu_context.h>
|
||||||
|
@ -1096,6 +1097,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
|
||||||
fput(bprm->file);
|
fput(bprm->file);
|
||||||
bprm->file = NULL;
|
bprm->file = NULL;
|
||||||
current->did_exec = 1;
|
current->did_exec = 1;
|
||||||
|
proc_exec_connector(current);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
read_lock(&binfmt_lock);
|
read_lock(&binfmt_lock);
|
||||||
|
|
127
include/linux/cn_proc.h
Normal file
127
include/linux/cn_proc.h
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* cn_proc.h - process events connector
|
||||||
|
*
|
||||||
|
* Copyright (C) Matt Helsley, IBM Corp. 2005
|
||||||
|
* Based on cn_fork.h by Nguyen Anh Quynh and Guillaume Thouvenin
|
||||||
|
* Original copyright notice follows:
|
||||||
|
* Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
|
||||||
|
* Copyright (C) 2005 Guillaume Thouvenin <guillaume.thouvenin@bull.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CN_PROC_H
|
||||||
|
#define CN_PROC_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/connector.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Userspace sends this enum to register with the kernel that it is listening
|
||||||
|
* for events on the connector.
|
||||||
|
*/
|
||||||
|
enum proc_cn_mcast_op {
|
||||||
|
PROC_CN_MCAST_LISTEN = 1,
|
||||||
|
PROC_CN_MCAST_IGNORE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* From the user's point of view, the process
|
||||||
|
* ID is the thread group ID and thread ID is the internal
|
||||||
|
* kernel "pid". So, fields are assigned as follow:
|
||||||
|
*
|
||||||
|
* In user space - In kernel space
|
||||||
|
*
|
||||||
|
* parent process ID = parent->tgid
|
||||||
|
* parent thread ID = parent->pid
|
||||||
|
* child process ID = child->tgid
|
||||||
|
* child thread ID = child->pid
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct proc_event {
|
||||||
|
enum what {
|
||||||
|
/* Use successive bits so the enums can be used to record
|
||||||
|
* sets of events as well
|
||||||
|
*/
|
||||||
|
PROC_EVENT_NONE = 0x00000000,
|
||||||
|
PROC_EVENT_FORK = 0x00000001,
|
||||||
|
PROC_EVENT_EXEC = 0x00000002,
|
||||||
|
PROC_EVENT_UID = 0x00000004,
|
||||||
|
PROC_EVENT_GID = 0x00000040,
|
||||||
|
/* "next" should be 0x00000400 */
|
||||||
|
/* "last" is the last process event: exit */
|
||||||
|
PROC_EVENT_EXIT = 0x80000000
|
||||||
|
} what;
|
||||||
|
__u32 cpu;
|
||||||
|
union { /* must be last field of proc_event struct */
|
||||||
|
struct {
|
||||||
|
__u32 err;
|
||||||
|
} ack;
|
||||||
|
|
||||||
|
struct fork_proc_event {
|
||||||
|
pid_t parent_pid;
|
||||||
|
pid_t parent_tgid;
|
||||||
|
pid_t child_pid;
|
||||||
|
pid_t child_tgid;
|
||||||
|
} fork;
|
||||||
|
|
||||||
|
struct exec_proc_event {
|
||||||
|
pid_t process_pid;
|
||||||
|
pid_t process_tgid;
|
||||||
|
} exec;
|
||||||
|
|
||||||
|
struct id_proc_event {
|
||||||
|
pid_t process_pid;
|
||||||
|
pid_t process_tgid;
|
||||||
|
union {
|
||||||
|
uid_t ruid; /* current->uid */
|
||||||
|
gid_t rgid; /* current->gid */
|
||||||
|
} r;
|
||||||
|
union {
|
||||||
|
uid_t euid;
|
||||||
|
gid_t egid;
|
||||||
|
} e;
|
||||||
|
} id;
|
||||||
|
|
||||||
|
struct exit_proc_event {
|
||||||
|
pid_t process_pid;
|
||||||
|
pid_t process_tgid;
|
||||||
|
__u32 exit_code, exit_signal;
|
||||||
|
} exit;
|
||||||
|
} event_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __KERNEL__
|
||||||
|
#ifdef CONFIG_PROC_EVENTS
|
||||||
|
void proc_fork_connector(struct task_struct *task);
|
||||||
|
void proc_exec_connector(struct task_struct *task);
|
||||||
|
void proc_id_connector(struct task_struct *task, int which_id);
|
||||||
|
void proc_exit_connector(struct task_struct *task);
|
||||||
|
#else
|
||||||
|
static inline void proc_fork_connector(struct task_struct *task)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline void proc_exec_connector(struct task_struct *task)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline void proc_id_connector(struct task_struct *task,
|
||||||
|
int which_id)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static inline void proc_exit_connector(struct task_struct *task)
|
||||||
|
{}
|
||||||
|
#endif /* CONFIG_PROC_EVENTS */
|
||||||
|
#endif /* __KERNEL__ */
|
||||||
|
#endif /* CN_PROC_H */
|
|
@ -27,6 +27,12 @@
|
||||||
#define CN_IDX_CONNECTOR 0xffffffff
|
#define CN_IDX_CONNECTOR 0xffffffff
|
||||||
#define CN_VAL_CONNECTOR 0xffffffff
|
#define CN_VAL_CONNECTOR 0xffffffff
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process Events connector unique ids -- used for message routing
|
||||||
|
*/
|
||||||
|
#define CN_IDX_PROC 0x1
|
||||||
|
#define CN_VAL_PROC 0x1
|
||||||
|
|
||||||
#define CN_NETLINK_USERS 1
|
#define CN_NETLINK_USERS 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/cpuset.h>
|
#include <linux/cpuset.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
#include <linux/signal.h>
|
#include <linux/signal.h>
|
||||||
|
#include <linux/cn_proc.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
|
@ -863,6 +864,7 @@ fastcall NORET_TYPE void do_exit(long code)
|
||||||
module_put(tsk->binfmt->module);
|
module_put(tsk->binfmt->module);
|
||||||
|
|
||||||
tsk->exit_code = code;
|
tsk->exit_code = code;
|
||||||
|
proc_exit_connector(tsk);
|
||||||
exit_notify(tsk);
|
exit_notify(tsk);
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
mpol_free(tsk->mempolicy);
|
mpol_free(tsk->mempolicy);
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/profile.h>
|
#include <linux/profile.h>
|
||||||
#include <linux/rmap.h>
|
#include <linux/rmap.h>
|
||||||
#include <linux/acct.h>
|
#include <linux/acct.h>
|
||||||
|
#include <linux/cn_proc.h>
|
||||||
|
|
||||||
#include <asm/pgtable.h>
|
#include <asm/pgtable.h>
|
||||||
#include <asm/pgalloc.h>
|
#include <asm/pgalloc.h>
|
||||||
|
@ -1143,6 +1144,7 @@ static task_t *copy_process(unsigned long clone_flags,
|
||||||
__get_cpu_var(process_counts)++;
|
__get_cpu_var(process_counts)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc_fork_connector(p);
|
||||||
if (!current->signal->tty && p->signal->tty)
|
if (!current->signal->tty && p->signal->tty)
|
||||||
p->signal->tty = NULL;
|
p->signal->tty = NULL;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/suspend.h>
|
#include <linux/suspend.h>
|
||||||
#include <linux/tty.h>
|
#include <linux/tty.h>
|
||||||
#include <linux/signal.h>
|
#include <linux/signal.h>
|
||||||
|
#include <linux/cn_proc.h>
|
||||||
|
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
|
@ -623,6 +624,7 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
|
||||||
current->egid = new_egid;
|
current->egid = new_egid;
|
||||||
current->gid = new_rgid;
|
current->gid = new_rgid;
|
||||||
key_fsgid_changed(current);
|
key_fsgid_changed(current);
|
||||||
|
proc_id_connector(current, PROC_EVENT_GID);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,6 +664,7 @@ asmlinkage long sys_setgid(gid_t gid)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
key_fsgid_changed(current);
|
key_fsgid_changed(current);
|
||||||
|
proc_id_connector(current, PROC_EVENT_GID);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,6 +754,7 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
|
||||||
current->fsuid = current->euid;
|
current->fsuid = current->euid;
|
||||||
|
|
||||||
key_fsuid_changed(current);
|
key_fsuid_changed(current);
|
||||||
|
proc_id_connector(current, PROC_EVENT_UID);
|
||||||
|
|
||||||
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE);
|
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE);
|
||||||
}
|
}
|
||||||
|
@ -798,6 +802,7 @@ asmlinkage long sys_setuid(uid_t uid)
|
||||||
current->suid = new_suid;
|
current->suid = new_suid;
|
||||||
|
|
||||||
key_fsuid_changed(current);
|
key_fsuid_changed(current);
|
||||||
|
proc_id_connector(current, PROC_EVENT_UID);
|
||||||
|
|
||||||
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID);
|
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID);
|
||||||
}
|
}
|
||||||
|
@ -846,6 +851,7 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
|
||||||
current->suid = suid;
|
current->suid = suid;
|
||||||
|
|
||||||
key_fsuid_changed(current);
|
key_fsuid_changed(current);
|
||||||
|
proc_id_connector(current, PROC_EVENT_UID);
|
||||||
|
|
||||||
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
|
return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
|
||||||
}
|
}
|
||||||
|
@ -898,6 +904,7 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
|
||||||
current->sgid = sgid;
|
current->sgid = sgid;
|
||||||
|
|
||||||
key_fsgid_changed(current);
|
key_fsgid_changed(current);
|
||||||
|
proc_id_connector(current, PROC_EVENT_GID);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -940,6 +947,7 @@ asmlinkage long sys_setfsuid(uid_t uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
key_fsuid_changed(current);
|
key_fsuid_changed(current);
|
||||||
|
proc_id_connector(current, PROC_EVENT_UID);
|
||||||
|
|
||||||
security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
|
security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
|
||||||
|
|
||||||
|
@ -968,6 +976,7 @@ asmlinkage long sys_setfsgid(gid_t gid)
|
||||||
}
|
}
|
||||||
current->fsgid = gid;
|
current->fsgid = gid;
|
||||||
key_fsgid_changed(current);
|
key_fsgid_changed(current);
|
||||||
|
proc_id_connector(current, PROC_EVENT_GID);
|
||||||
}
|
}
|
||||||
return old_fsgid;
|
return old_fsgid;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue