Skip to contentSkip to conversation

/proc/$$/ipaddr and per-task networking bits

PATCH In review Lorenzo Hernández García-Hierro 6 participants 10 messages Mar 10, 2005 – Mar 11, 2005

Subsystems (6)
Networking VFS Scheduler TCP +2 more subsystems
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 /proc/$$/ipaddr and per-task networking bits

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

---

 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(+)
fs/proc/base.c renamed from fs/proc/base.c~task-curr_ip +12 -0
diff -puN fs/proc/base.c~task-curr_ip fs/proc/base.c
@@ -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;
fs/proc/internal.h renamed from fs/proc/internal.h~task-curr_ip +3 -0
diff -puN fs/proc/internal.h~task-curr_ip fs/proc/internal.h
@@ -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)
 {
fs/proc/array.c renamed from fs/proc/array.c~task-curr_ip +10 -0
diff -puN fs/proc/array.c~task-curr_ip fs/proc/array.c
@@ -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
fs/Kconfig renamed from fs/Kconfig~task-curr_ip +16 -0
diff -puN fs/Kconfig~task-curr_ip fs/Kconfig
@@ -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
+	  [email protected].
 
 config SYSFS
 	bool "sysfs file system support" if EMBEDDED
net/socket.c renamed from net/socket.c~task-curr_ip +2 -0
diff -puN net/socket.c~task-curr_ip net/socket.c
@@ -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);
include/linux/sched.h renamed from include/linux/sched.h~task-curr_ip +8 -0
diff -puN include/linux/sched.h~task-curr_ip include/linux/sched.h
@@ -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)
net/ipv4/tcp_ipv4.c renamed from net/ipv4/tcp_ipv4.c~task-curr_ip +14 -0
diff -puN net/ipv4/tcp_ipv4.c~task-curr_ip net/ipv4/tcp_ipv4.c
@@ -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);
kernel/exit.c renamed from kernel/exit.c~task-curr_ip +8 -0
diff -puN kernel/exit.c~task-curr_ip kernel/exit.c
@@ -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);
net/proc_ipaddr.c new file +166 -0

166 lines not on this page · raw message

net/Makefile renamed from net/Makefile~task-curr_ip +4 -0
diff -puN net/Makefile~task-curr_ip net/Makefile
@@ -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,

Signature · 2 lines
Lorenzo Hernández García-Hierro <[email protected]> 
[1024D/6F2B2DEC] & [2048g/9AE91A22][http://tuxedo-es.org]
#1 lore raw
Quoted 6 lines · Lorenzo Hernández García-Hierro

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

a few questions
1) Why is this a config option; if it's useful it should just be always on really
2) Can you explain briefly what this is useful for?
3) How does this work for existing stuff if, say, your dhcp lease changes and your machine no longer owns a certain IP, what will happen to the tasks?
4) if a machine has multiple IPs.. which one is chosen ?

#2 lore raw
Quoted 3 lines · Arjan van de Ven

a few questions
1) Why is this a config option; if it's useful it should just be always on really

Just to be removed if it applies for mainline.

Quoted 1 line

2) Can you explain briefly what this is useful for?

For keeping track on the "originating ip address of the task/process" (the ipv4 address of the user that started the task/process).
It adds an ipaddr entry if available for each /proc/<pid> entry, among the API changes.

Example:

root@dg:/usr/src# cat /proc/5907/ipaddr
192.128.102.93
Quoted 4 lines

3) How does this work for existing stuff if, say, your dhcp lease changes and your machine no longer owns a certain IP, what will happen to the tasks?
4) if a machine has multiple IPs.. which one is chosen ?

The patch has nothing to do with this, as it's objective is different. See http://lkml.org/lkml/2005/3/10/108 and
http://pearls.tuxedo-es.org/patches/selinux-avc_audit-log-curr_ip.patch
if you want useful and real examples on how it works and helps.

Cheers,

Signature · 2 lines
Lorenzo Hernández García-Hierro <[email protected]> 
[1024D/6F2B2DEC] & [2048g/9AE91A22][http://tuxedo-es.org]
#3 lore raw
Quoted 5 lines · Lorenzo Hernández García-Hierro
Quoted 1 line

2) Can you explain briefly what this is useful for?

For keeping track on the "originating ip address of the task/process" (the ipv4 address of the user that started the task/process).

but.... tasks don't have an IP address. Hosts do. Hosts can have multiple IP addresses. Both ipv4 and ipv6. Users don't have IP addresses either (they do have user IDs so that link is clear). I think I'm missing something big here. What does it *mean* for a task to have an IP address. Once that is clear maybe I can start to understand the rest, but until the meaning of "task has an IP address" is better explained/more clear I think I'm stuck. (and no the output in a log isn't a meaning, it's only a result)

#4 lore raw
Quoted 8 lines · Arjan van de Ven

but.... tasks don't have an IP address. Hosts do. Hosts can have multiple IP addresses. Both ipv4 and ipv6. Users don't have IP addresses either (they do have user IDs so that link is clear). I think I'm missing something big here. What does it *mean* for a task to have an IP address. Once that is clear maybe I can start to understand the rest, but until the meaning of "task has an IP address" is better explained/more clear I think I'm stuck. (and no the output in a log isn't a meaning, it's only a result)

I think I've explained it well, more concretely, it tries to fill the ipaddr member of the task_struct structure with the IP address associated to the user running @current task/process,if available. Then, it will be attached within the proc fs in an entry called ipaddr, under the proper pid directory.

The whole thing is almost self-explaining by just looking at the code.

Cheers,

Signature · 2 lines
Lorenzo Hernández García-Hierro <[email protected]> 
[1024D/6F2B2DEC] & [2048g/9AE91A22][http://tuxedo-es.org]
#5 lore raw

On Thu, 2005-03-10 at 17:00 +0100, Lorenzo Hernández García-Hierro
wrote: it tries to fill the

Quoted 2 lines

ipaddr member of the task_struct structure with the IP address associated to the user running @current task/process,if available.

but... a use doesn't hane an IP. a host does.

#6 lore raw

Replying to Arjan van de Ven:

Quoted 6 lines

On Thu, 2005-03-10 at 17:00 +0100, Lorenzo Hernández García-Hierro
wrote: it tries to fill the

Quoted 2 lines

ipaddr member of the task_struct structure with the IP address associated to the user running @current task/process,if available.

but... a use doesn't hane an IP. a host does.

I don't get it too
With multihomed setup same process I have can send and receive on many addresses simultaneously. So single ip_addr cannot describe this situation.

Signature · 2 lines
Paul P 'Stingray' Komkoff Jr // http://stingr.net/key <- my pgp key
 This message represents the official view of the voices in my head
#7 lore raw
In reply to Arjan van de Ven
Quoted 6 lines · Arjan van de Ven

On Thu, 2005-03-10 at 17:00 +0100, Lorenzo Hernández García-Hierro
wrote: it tries to fill the

Quoted 2 lines

ipaddr member of the task_struct structure with the IP address associated to the user running @current task/process,if available.

but... a use doesn't hane an IP. a host does.

I'm not sure i understand but i've just tried to read the code and it looks like the IP address is the address of the other end of a socket.

This address is set when a process does accept(). So this user IP we are talking about would be the remote users host IP (or gateway in case of NAT).

I don't think i fully understand the code but it looks like it only holds the remote IP address of the last accept()-ed connection.

Joost Remijn

#8 lore raw
In reply to Arjan van de Ven
Quoted 7 lines · Arjan van de Ven

On Thu, 2005-03-10 at 17:00 +0100, Lorenzo Hernández García-Hierro
wrote: it tries to fill the

Quoted 2 lines

ipaddr member of the task_struct structure with the IP address associated to the user running @current task/process,if available.

but... a use doesn't hane an IP. a host does.

The patch is useful in this situation. Suppose node E has two IPs, IP1 and IP2. IP1 is the default and got blocked from some network C.

Now if one try to visit C from E, one has to to use IP2.

Signature · 2 lines
Coywolf Qi Hunt
Homepage http://sosdg.org/~coywolf/
#9 lore raw
In reply to Lorenzo Hernández García-Hierro

In article <[email protected]> (at Thu, 10 Mar 2005 15:16:42 +0100), Lorenzo Hernández García-Hierro <[email protected]> says:

Quoted 6 lines

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

Please don't.

You already can get this information via procfs; e.g. lsof does, It does support IPv6 as well.

--yoshfuji