From: "Lorenzo Hernández García-Hierro" <lorenzo@gnu.org>
To: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: [patch 1/1] /proc/$$/ipaddr and per-task networking bits
Date: Thu, 10 Mar 2005 15:16:42 +0100 [thread overview]
Message-ID: <1110464202.9190.7.camel@localhost.localdomain> (raw)
[-- Attachment #1: Type: text/plain, Size: 13278 bytes --]
Ported feature from grSecurity that makes possible to add an ipaddr
entry in each /proc/<pid> (/proc/<pid>/ipaddr), where the task originating
IP address is stored, and subsequently made available (readable) by the process
itself and also the root user with CAP_DAC_OVERRIDE capability (that can be managed
by specific security models implementations like SELinux).
Available also at http://pearls.tuxedo-es.org/patches/task-curr_ip.patch
Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@gnu.org>
---
linux-2.6.11-lorenzo/fs/Kconfig | 16 ++
linux-2.6.11-lorenzo/fs/proc/array.c | 10 +
linux-2.6.11-lorenzo/fs/proc/base.c | 12 ++
linux-2.6.11-lorenzo/fs/proc/internal.h | 3
linux-2.6.11-lorenzo/include/linux/sched.h | 8 +
linux-2.6.11-lorenzo/kernel/exit.c | 8 +
linux-2.6.11-lorenzo/net/Makefile | 4
linux-2.6.11-lorenzo/net/ipv4/tcp_ipv4.c | 14 ++
linux-2.6.11-lorenzo/net/proc_ipaddr.c | 166 +++++++++++++++++++++++++++++
linux-2.6.11-lorenzo/net/socket.c | 2
10 files changed, 243 insertions(+)
diff -puN fs/proc/base.c~task-curr_ip fs/proc/base.c
--- linux-2.6.11/fs/proc/base.c~task-curr_ip 2005-03-10 14:56:13.931854168 +0100
+++ linux-2.6.11-lorenzo/fs/proc/base.c 2005-03-10 14:56:14.048836384 +0100
@@ -74,6 +74,9 @@ enum pid_directory_inos {
#ifdef CONFIG_AUDITSYSCALL
PROC_TGID_LOGINUID,
#endif
+#ifdef CONFIG_PROC_IPADDR
+ PROC_TGID_IPADDR,
+#endif
PROC_TGID_FD_DIR,
PROC_TGID_OOM_SCORE,
PROC_TGID_OOM_ADJUST,
@@ -134,6 +137,9 @@ static struct pid_entry tgid_base_stuff[
E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO),
E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO),
E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO),
+#ifdef CONFIG_PROC_IPADDR
+ E(PROC_TGID_IPADDR, "ipaddr", S_IFREG|S_IRUSR),
+#endif
#ifdef CONFIG_SECURITY
E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO),
#endif
@@ -1416,6 +1422,12 @@ static struct dentry *proc_pident_lookup
inode->i_fop = &proc_info_file_operations;
ei->op.proc_read = proc_pid_status;
break;
+#ifdef CONFIG_PROC_IPADDR
+ case PROC_TGID_IPADDR:
+ inode->i_fop = &proc_info_file_operations;
+ ei->op.proc_read = proc_pid_ipaddr;
+ break;
+#endif
case PROC_TID_STAT:
inode->i_fop = &proc_info_file_operations;
ei->op.proc_read = proc_tid_stat;
diff -puN fs/proc/internal.h~task-curr_ip fs/proc/internal.h
--- linux-2.6.11/fs/proc/internal.h~task-curr_ip 2005-03-10 14:56:13.932854016 +0100
+++ linux-2.6.11-lorenzo/fs/proc/internal.h 2005-03-10 14:56:14.048836384 +0100
@@ -36,6 +36,9 @@ extern int proc_tid_stat(struct task_str
extern int proc_tgid_stat(struct task_struct *, char *);
extern int proc_pid_status(struct task_struct *, char *);
extern int proc_pid_statm(struct task_struct *, char *);
+#ifdef CONFIG_PROC_IPADDR
+extern int proc_pid_ipaddr(struct task_struct*,char*);
+#endif
static inline struct task_struct *proc_task(struct inode *inode)
{
diff -puN fs/proc/array.c~task-curr_ip fs/proc/array.c
--- linux-2.6.11/fs/proc/array.c~task-curr_ip 2005-03-10 14:56:13.934853712 +0100
+++ linux-2.6.11-lorenzo/fs/proc/array.c 2005-03-10 14:56:14.048836384 +0100
@@ -473,3 +473,13 @@ int proc_pid_statm(struct task_struct *t
return sprintf(buffer,"%d %d %d %d %d %d %d\n",
size, resident, shared, text, lib, data, 0);
}
+
+#ifdef CONFIG_PROC_IPADDR
+int proc_pid_ipaddr(struct task_struct *task, char * buffer)
+{
+ int len;
+
+ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
+ return len;
+}
+#endif
diff -puN fs/Kconfig~task-curr_ip fs/Kconfig
--- linux-2.6.11/fs/Kconfig~task-curr_ip 2005-03-10 14:56:13.936853408 +0100
+++ linux-2.6.11-lorenzo/fs/Kconfig 2005-03-10 14:56:14.049836232 +0100
@@ -716,6 +716,22 @@ config PROC_FS
config PROC_KCORE
bool "/proc/kcore support" if !ARM
depends on PROC_FS && MMU
+
+config PROC_IPADDR
+ bool "/proc/<pid>/ipaddr support"
+ depends on PROC_FS && NET && INET
+ help
+ If you say Y here, a new entry will be added to each /proc/<pid>
+ directory that contains the IP address of the person using the task.
+ The IP is carried across local TCP and AF_UNIX stream sockets.
+ This information can be useful for IDS/IPSes to perform remote response
+ to a local attack. The entry is readable by only the owner of the
+ process (and root if he has CAP_DAC_OVERRIDE, which can be handled in
+ different manners depending on the used model, ie. RBAC and the engine
+ implementing it, ie. SELinux), and thus does not create privacy concerns.
+
+ This feature has been ported out of grSecurity from Brad Spengler by
+ lorenzo@gnu.org.
config SYSFS
bool "sysfs file system support" if EMBEDDED
diff -puN net/socket.c~task-curr_ip net/socket.c
--- linux-2.6.11/net/socket.c~task-curr_ip 2005-03-10 14:56:13.938853104 +0100
+++ linux-2.6.11-lorenzo/net/socket.c 2005-03-10 14:56:14.050836080 +0100
@@ -114,6 +114,7 @@ static ssize_t sock_writev(struct file *
static ssize_t sock_sendpage(struct file *file, struct page *page,
int offset, size_t size, loff_t *ppos, int more);
+extern void proc_attach_curr_ip(const struct sock *sk);
/*
* Socket files have a set of 'special' operations as well as the generic file ones. These don't appear
@@ -1386,6 +1387,7 @@ asmlinkage long sys_accept(int fd, struc
goto out_release;
security_socket_post_accept(sock, newsock);
+ proc_attach_curr_ip(newsock->sk);
out_put:
sockfd_put(sock);
diff -puN include/linux/sched.h~task-curr_ip include/linux/sched.h
--- linux-2.6.11/include/linux/sched.h~task-curr_ip 2005-03-10 14:56:13.963849304 +0100
+++ linux-2.6.11-lorenzo/include/linux/sched.h 2005-03-10 14:56:14.051835928 +0100
@@ -685,6 +685,14 @@ struct task_struct {
struct mempolicy *mempolicy;
short il_next;
#endif
+#ifdef CONFIG_PROC_IPADDR
+ u32 curr_ip; /* per-task originating ip address */
+ u8 used_accept:1;
+ u32 net_saddr;
+ u32 net_daddr;
+ u16 net_sport;
+ u16 net_dport;
+#endif
};
static inline pid_t process_group(struct task_struct *tsk)
diff -puN net/ipv4/tcp_ipv4.c~task-curr_ip net/ipv4/tcp_ipv4.c
--- linux-2.6.11/net/ipv4/tcp_ipv4.c~task-curr_ip 2005-03-10 14:56:13.977847176 +0100
+++ linux-2.6.11-lorenzo/net/ipv4/tcp_ipv4.c 2005-03-10 14:56:14.052835776 +0100
@@ -82,6 +82,11 @@ int sysctl_tcp_low_latency;
/* Check TCP sequence numbers in ICMP packets. */
#define ICMP_MIN_LENGTH 8
+#ifdef CONFIG_PROC_IPADDR
+extern void net_add_to_task_ip_table(struct task_struct *p);
+extern void net_del_task_from_ip_table(struct task_struct *p);
+#endif
+
/* Socket used for sending RSTs */
static struct socket *tcp_socket;
@@ -717,6 +722,15 @@ ok:
__tcp_v4_hash(sk, 0);
}
spin_unlock(&head->lock);
+
+#ifdef CONFIG_PROC_IPADDR
+ net_del_task_from_ip_table(current);
+ current->net_saddr = inet_sk(sk)->rcv_saddr;
+ current->net_daddr = inet_sk(sk)->daddr;
+ current->net_sport = inet_sk(sk)->sport;
+ current->net_dport = inet_sk(sk)->dport;
+ net_add_to_task_ip_table(current);
+#endif
if (tw) {
tcp_tw_deschedule(tw);
diff -puN kernel/exit.c~task-curr_ip kernel/exit.c
--- linux-2.6.11/kernel/exit.c~task-curr_ip 2005-03-10 14:56:13.979846872 +0100
+++ linux-2.6.11-lorenzo/kernel/exit.c 2005-03-10 14:56:14.053835624 +0100
@@ -35,6 +35,10 @@
extern void sem_exit (void);
extern struct task_struct *child_reaper;
+#ifdef CONFIG_PROC_IPADDR
+extern void net_del_task_from_ip_table(struct task_struct *p);
+#endif
+
int getrusage(struct task_struct *, int, struct rusage __user *);
static void __unhash_process(struct task_struct *p)
@@ -811,6 +815,10 @@ fastcall NORET_TYPE void do_exit(long co
group_dead = atomic_dec_and_test(&tsk->signal->live);
if (group_dead)
acct_process(code);
+
+#ifdef CONFIG_PROC_IPADDR
+ net_del_task_from_ip_table(tsk);
+#endif
exit_mm(tsk);
exit_sem(tsk);
diff -puN /dev/null net/proc_ipaddr.c
--- /dev/null 2005-03-01 21:41:03.335473768 +0100
+++ linux-2.6.11-lorenzo/net/proc_ipaddr.c 2005-03-10 14:56:14.054835472 +0100
@@ -0,0 +1,166 @@
+/*
+ * Per-task originating IP address & /proc/$$/ipaddr entry support.
+ *
+ * Copyright (C) 2005 Lorenzo Hernandez Garcia-Hierro <lorenzo@gnu.org>
+ * Copyright (C) 2004, 2005 Brad Spengler <spender@grsecurity.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/file.h>
+#include <linux/net.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <net/sock.h>
+
+#ifdef CONFIG_PROC_IPADDR
+#define net_conn_table_size 65521
+struct task_struct *net_conn_table[net_conn_table_size];
+struct task_struct *deleted_conn = (struct task_struct *)~0;
+spinlock_t net_conn_table_lock = SPIN_LOCK_UNLOCKED;
+
+static __inline__ int
+conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
+{
+ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
+}
+
+static __inline__ int
+conn_match(const struct task_struct *task, __u32 saddr, __u32 daddr,
+ __u16 sport, __u16 dport)
+{
+ if (unlikely(task != deleted_conn && task->net_saddr == saddr &&
+ task->net_daddr == daddr && task->net_sport == sport &&
+ task->net_dport == dport))
+ return 1;
+ else
+ return 0;
+}
+
+void net_add_to_task_ip_table(struct task_struct *task)
+{
+ unsigned int index;
+
+ if (unlikely(net_conn_table == NULL))
+ return;
+
+ if (!thread_group_leader(task))
+ task = task->group_leader;
+
+ index = conn_hash(task->net_saddr, task->net_daddr,
+ task->net_sport, task->net_dport,
+ net_conn_table_size);
+
+ spin_lock(&net_conn_table_lock);
+
+ while (net_conn_table[index] && net_conn_table[index] != deleted_conn) {
+ index = (index + 1) % net_conn_table_size;
+ }
+
+ net_conn_table[index] = task;
+
+ spin_unlock(&net_conn_table_lock);
+
+ return;
+}
+
+void net_del_task_from_ip_table_nolock(struct task_struct *task)
+{
+ unsigned int index;
+
+ if (unlikely(net_conn_table == NULL))
+ return;
+
+ if (!thread_group_leader(task))
+ task = task->group_leader;
+
+ index = conn_hash(task->net_saddr, task->net_daddr,
+ task->net_sport, task->net_dport,
+ net_conn_table_size);
+
+ while (net_conn_table[index] && !conn_match(net_conn_table[index],
+ task->net_saddr, task->net_daddr, task->net_sport,
+ task->net_dport)) {
+ index = (index + 1) % net_conn_table_size;
+ }
+
+ if (net_conn_table[index]) {
+ if (net_conn_table[(index + 1) % net_conn_table_size])
+ net_conn_table[index] = deleted_conn;
+ else
+ net_conn_table[index] = NULL;
+ }
+
+ return;
+}
+
+struct task_struct * net_lookup_task_ip_table(__u32 saddr, __u32 daddr,
+ __u16 sport, __u16 dport)
+{
+ unsigned int index;
+
+ if (unlikely(net_conn_table == NULL))
+ return NULL;
+
+ index = conn_hash(saddr, daddr, sport, dport, net_conn_table_size);
+
+ while (net_conn_table[index] && !conn_match(net_conn_table[index],
+ saddr, daddr, sport, dport)) {
+ index = (index + 1) % net_conn_table_size;
+ }
+
+ return net_conn_table[index];
+}
+#endif
+
+void net_del_task_from_ip_table(struct task_struct *task)
+{
+#ifdef CONFIG_PROC_IPADDR
+ spin_lock(&net_conn_table_lock);
+ if (!thread_group_leader(task))
+ net_del_task_from_ip_table_nolock(task->group_leader);
+ else
+ net_del_task_from_ip_table_nolock(task);
+ spin_unlock(&net_conn_table_lock);
+#endif
+ return;
+}
+
+void
+proc_attach_curr_ip(const struct sock *sk)
+{
+#ifdef CONFIG_PROC_IPADDR
+ struct task_struct *p;
+ struct task_struct *set;
+ const struct inet_sock *inet = inet_sk(sk);
+
+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
+ return;
+
+ set = current;
+ if (!thread_group_leader(set))
+ set = set->group_leader;
+
+ spin_lock(&net_conn_table_lock);
+ p = net_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
+ inet->dport, inet->sport);
+ if (unlikely(p != NULL)) {
+ set->curr_ip = p->curr_ip;
+ set->used_accept = 1;
+ net_del_task_from_ip_table_nolock(p);
+ spin_unlock(&net_conn_table_lock);
+ return;
+ }
+ spin_unlock(&net_conn_table_lock);
+
+ set->curr_ip = inet->daddr;
+ set->used_accept = 1;
+#endif
+ return;
+}
diff -puN net/Makefile~task-curr_ip net/Makefile
--- linux-2.6.11/net/Makefile~task-curr_ip 2005-03-10 14:56:13.981846568 +0100
+++ linux-2.6.11-lorenzo/net/Makefile 2005-03-10 14:56:14.054835472 +0100
@@ -46,3 +46,7 @@ obj-$(CONFIG_IP_SCTP) += sctp/
ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_SYSCTL) += sysctl_net.o
endif
+
+ifeq ($(CONFIG_NET),y)
+obj-$(CONFIG_PROC_IPADDR) += proc_ipaddr.o
+endif
Cheers,
--
Lorenzo Hernández García-Hierro <lorenzo@gnu.org>
[1024D/6F2B2DEC] & [2048g/9AE91A22][http://tuxedo-es.org]
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
next reply other threads:[~2005-03-10 14:18 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-03-10 14:16 Lorenzo Hernández García-Hierro [this message]
2005-03-10 14:26 ` [patch 1/1] /proc/$$/ipaddr and per-task networking bits Arjan van de Ven
2005-03-10 15:28 ` Lorenzo Hernández García-Hierro
2005-03-10 15:38 ` Arjan van de Ven
2005-03-10 16:00 ` Lorenzo Hernández García-Hierro
2005-03-10 16:08 ` Arjan van de Ven
2005-03-10 16:19 ` Paul P Komkoff Jr
2005-03-10 16:36 ` Joost Remijn
2005-03-11 12:35 ` Coywolf Qi Hunt
2005-03-10 15:22 ` YOSHIFUJI Hideaki / 吉藤英明
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1110464202.9190.7.camel@localhost.localdomain \
--to=lorenzo@gnu.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.