Blame view

net/ax25/ax25_uid.c 4.8 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
  /*
   * 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.
   *
   * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
   */
4fc268d24   Randy Dunlap   [PATCH] capable/c...
9
10
  
  #include <linux/capability.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
13
14
15
  #include <linux/errno.h>
  #include <linux/types.h>
  #include <linux/socket.h>
  #include <linux/in.h>
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
19
20
  #include <linux/timer.h>
  #include <linux/string.h>
  #include <linux/sockios.h>
  #include <linux/net.h>
  #include <linux/spinlock.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
21
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
26
27
28
  #include <net/ax25.h>
  #include <linux/inet.h>
  #include <linux/netdevice.h>
  #include <linux/if_arp.h>
  #include <linux/skbuff.h>
  #include <net/sock.h>
  #include <asm/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
30
31
  #include <linux/fcntl.h>
  #include <linux/mm.h>
  #include <linux/interrupt.h>
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
32
  #include <linux/list.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
35
36
  #include <linux/notifier.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
  #include <linux/stat.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
  #include <linux/sysctl.h>
bc3b2d7fb   Paul Gortmaker   net: Add export.h...
38
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
44
  #include <net/ip.h>
  #include <net/arp.h>
  
  /*
   *	Callsign/UID mapper. This is in kernel space for security on multi-amateur machines.
   */
f16f3026d   Eric Dumazet   [AX25]: sparse cl...
45
  static HLIST_HEAD(ax25_uid_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  static DEFINE_RWLOCK(ax25_uid_lock);
f16f3026d   Eric Dumazet   [AX25]: sparse cl...
47
  int ax25_uid_policy;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48

70868eace   Ralf Baechle   [AX.25]: Move AX....
49
  EXPORT_SYMBOL(ax25_uid_policy);
d13fda856   Eric W. Biederman   userns: Convert n...
50
  ax25_uid_assoc *ax25_findbyuid(kuid_t uid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
  {
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
52
  	ax25_uid_assoc *ax25_uid, *res = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
54
  
  	read_lock(&ax25_uid_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
55
  	ax25_uid_for_each(ax25_uid, &ax25_uid_list) {
d13fda856   Eric W. Biederman   userns: Convert n...
56
  		if (uid_eq(ax25_uid->uid, uid)) {
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
57
58
  			ax25_uid_hold(ax25_uid);
  			res = ax25_uid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
  			break;
  		}
  	}
  	read_unlock(&ax25_uid_lock);
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
63
  	return res;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
  }
70868eace   Ralf Baechle   [AX.25]: Move AX....
65
  EXPORT_SYMBOL(ax25_findbyuid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
  int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
  {
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
68
  	ax25_uid_assoc *ax25_uid;
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
69
  	ax25_uid_assoc *user;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
72
73
74
75
  	unsigned long res;
  
  	switch (cmd) {
  	case SIOCAX25GETUID:
  		res = -ENOENT;
  		read_lock(&ax25_uid_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
76
  		ax25_uid_for_each(ax25_uid, &ax25_uid_list) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  			if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) {
d13fda856   Eric W. Biederman   userns: Convert n...
78
  				res = from_kuid_munged(current_user_ns(), ax25_uid->uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
81
82
83
84
85
86
  				break;
  			}
  		}
  		read_unlock(&ax25_uid_lock);
  
  		return res;
  
  	case SIOCAX25ADDUID:
d13fda856   Eric W. Biederman   userns: Convert n...
87
88
  	{
  		kuid_t sax25_kuid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
  		if (!capable(CAP_NET_ADMIN))
  			return -EPERM;
d13fda856   Eric W. Biederman   userns: Convert n...
91
92
93
94
  		sax25_kuid = make_kuid(current_user_ns(), sax->sax25_uid);
  		if (!uid_valid(sax25_kuid))
  			return -EINVAL;
  		user = ax25_findbyuid(sax25_kuid);
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
95
96
  		if (user) {
  			ax25_uid_put(user);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
  			return -EEXIST;
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
98
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
101
102
  		if (sax->sax25_uid == 0)
  			return -EINVAL;
  		if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL)
  			return -ENOMEM;
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
103
  		atomic_set(&ax25_uid->refcount, 1);
d13fda856   Eric W. Biederman   userns: Convert n...
104
  		ax25_uid->uid  = sax25_kuid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
107
  		ax25_uid->call = sax->sax25_call;
  
  		write_lock(&ax25_uid_lock);
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
108
  		hlist_add_head(&ax25_uid->uid_node, &ax25_uid_list);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
111
  		write_unlock(&ax25_uid_lock);
  
  		return 0;
d13fda856   Eric W. Biederman   userns: Convert n...
112
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
  	case SIOCAX25DELUID:
  		if (!capable(CAP_NET_ADMIN))
  			return -EPERM;
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
116
  		ax25_uid = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  		write_lock(&ax25_uid_lock);
b67bfe0d4   Sasha Levin   hlist: drop the n...
118
  		ax25_uid_for_each(ax25_uid, &ax25_uid_list) {
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
119
  			if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
  				break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
123
124
125
  		}
  		if (ax25_uid == NULL) {
  			write_unlock(&ax25_uid_lock);
  			return -ENOENT;
  		}
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
126
127
  		hlist_del_init(&ax25_uid->uid_node);
  		ax25_uid_put(ax25_uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
  		write_unlock(&ax25_uid_lock);
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
129
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
131
132
133
134
135
136
137
138
139
140
  
  	default:
  		return -EINVAL;
  	}
  
  	return -EINVAL;	/*NOTREACHED */
  }
  
  #ifdef CONFIG_PROC_FS
  
  static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos)
f16f3026d   Eric Dumazet   [AX25]: sparse cl...
141
  	__acquires(ax25_uid_lock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
  	read_lock(&ax25_uid_lock);
b512f3d84   Li Zefan   net: ax25: use se...
144
  	return seq_hlist_start_head(&ax25_uid_list, *pos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
  }
  
  static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  {
b512f3d84   Li Zefan   net: ax25: use se...
149
  	return seq_hlist_next(v, &ax25_uid_list, pos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150
151
152
  }
  
  static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
f16f3026d   Eric Dumazet   [AX25]: sparse cl...
153
  	__releases(ax25_uid_lock)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
157
158
159
  {
  	read_unlock(&ax25_uid_lock);
  }
  
  static int ax25_uid_seq_show(struct seq_file *seq, void *v)
  {
f75268cd6   Ralf Baechle   [AX25]: Make ax2a...
160
  	char buf[11];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
164
  	if (v == SEQ_START_TOKEN)
  		seq_printf(seq, "Policy: %d
  ", ax25_uid_policy);
  	else {
b512f3d84   Li Zefan   net: ax25: use se...
165
  		struct ax25_uid_assoc *pt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166

b512f3d84   Li Zefan   net: ax25: use se...
167
  		pt = hlist_entry(v, struct ax25_uid_assoc, uid_node);
d13fda856   Eric W. Biederman   userns: Convert n...
168
169
170
171
  		seq_printf(seq, "%6d %s
  ",
  			from_kuid_munged(seq_user_ns(seq), pt->uid),
  			ax2asc(buf, &pt->call));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
174
  	}
  	return 0;
  }
56b3d975b   Philippe De Muyter   [NET]: Make all i...
175
  static const struct seq_operations ax25_uid_seqops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
178
179
180
181
182
183
184
185
  	.start = ax25_uid_seq_start,
  	.next = ax25_uid_seq_next,
  	.stop = ax25_uid_seq_stop,
  	.show = ax25_uid_seq_show,
  };
  
  static int ax25_uid_info_open(struct inode *inode, struct file *file)
  {
  	return seq_open(file, &ax25_uid_seqops);
  }
9a32144e9   Arjan van de Ven   [PATCH] mark stru...
186
  const struct file_operations ax25_uid_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
188
189
190
191
192
193
194
195
196
197
198
199
200
  	.owner = THIS_MODULE,
  	.open = ax25_uid_info_open,
  	.read = seq_read,
  	.llseek = seq_lseek,
  	.release = seq_release,
  };
  
  #endif
  
  /*
   *	Free all memory associated with UID/Callsign structures.
   */
  void __exit ax25_uid_free(void)
  {
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
201
  	ax25_uid_assoc *ax25_uid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
203
  
  	write_lock(&ax25_uid_lock);
ae1b6a31b   Pavel Emelyanov   [AX25]: Potential...
204
  again:
b67bfe0d4   Sasha Levin   hlist: drop the n...
205
  	ax25_uid_for_each(ax25_uid, &ax25_uid_list) {
01d7dd0e9   Ralf Baechle   [AX25]: UID fixes
206
207
  		hlist_del_init(&ax25_uid->uid_node);
  		ax25_uid_put(ax25_uid);
ae1b6a31b   Pavel Emelyanov   [AX25]: Potential...
208
  		goto again;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
  	write_unlock(&ax25_uid_lock);
  }