]>
Commit | Line | Data |
---|---|---|
8f71d8af | 1 | audits |
2 | rename | |
3 | netlink | |
4 | diff -urp a/grsecurity/gracl.c c/grsecurity/gracl.c | |
5 | --- a/grsecurity/gracl.c 2007-12-10 23:52:36.040492750 +0100 | |
6 | +++ c/grsecurity/gracl.c 2007-12-11 00:32:38.094611750 +0100 | |
7 | @@ -329,7 +329,7 @@ to_gr_audit(const __u32 reqmode) | |
8 | /* masks off auditable permission flags, then shifts them to create | |
9 | auditing flags, and adds the special case of append auditing if | |
10 | we're requesting write */ | |
11 | - return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0)); | |
12 | + return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0)); | |
13 | } | |
14 | ||
15 | struct acl_subject_label * | |
16 | @@ -519,6 +519,35 @@ lookup_name_entry(const char *name) | |
17 | return match; | |
18 | } | |
19 | ||
20 | +static struct name_entry * | |
21 | +lookup_name_entry_create(const char *name) | |
22 | +{ | |
23 | + unsigned int len = strlen(name); | |
24 | + unsigned int key = full_name_hash(name, len); | |
25 | + unsigned int index = key % name_set.n_size; | |
26 | + struct name_entry *match; | |
27 | + | |
28 | + match = name_set.n_hash[index]; | |
29 | + | |
30 | + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) || | |
31 | + !match->deleted)) | |
32 | + match = match->next; | |
33 | + | |
34 | + if (match && match->deleted) | |
35 | + return match; | |
36 | + | |
37 | + match = name_set.n_hash[index]; | |
38 | + | |
39 | + while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) || | |
40 | + match->deleted)) | |
41 | + match = match->next; | |
42 | + | |
43 | + if (match && !match->deleted) | |
44 | + return match; | |
45 | + else | |
46 | + return NULL; | |
47 | +} | |
48 | + | |
49 | static struct inodev_entry * | |
50 | lookup_inodev_entry(const ino_t ino, const dev_t dev) | |
51 | { | |
52 | @@ -584,7 +613,7 @@ insert_acl_role_label(struct acl_role_la | |
53 | } | |
54 | ||
55 | static int | |
56 | -insert_name_entry(char *name, const ino_t inode, const dev_t device) | |
57 | +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted) | |
58 | { | |
59 | struct name_entry **curr, *nentry; | |
60 | struct inodev_entry *ientry; | |
61 | @@ -613,6 +642,7 @@ insert_name_entry(char *name, const ino_ | |
62 | nentry->inode = inode; | |
63 | nentry->device = device; | |
64 | nentry->len = len; | |
65 | + nentry->deleted = deleted; | |
66 | ||
67 | nentry->prev = NULL; | |
68 | curr = &name_set.n_hash[index]; | |
69 | @@ -975,7 +1005,7 @@ copy_user_objs(struct acl_object_label * | |
70 | ||
71 | insert_acl_obj_label(o_tmp, subj); | |
72 | if (!insert_name_entry(o_tmp->filename, o_tmp->inode, | |
73 | - o_tmp->device)) | |
74 | + o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0)) | |
75 | return -ENOMEM; | |
76 | ||
77 | ret = copy_user_glob(o_tmp); | |
78 | @@ -1270,7 +1300,7 @@ do_copy_user_subj(struct acl_subject_lab | |
79 | ||
80 | insert: | |
81 | if (!insert_name_entry(s_tmp->filename, s_tmp->inode, | |
82 | - s_tmp->device)) | |
83 | + s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0)) | |
84 | return ERR_PTR(-ENOMEM); | |
85 | ||
86 | return s_tmp; | |
87 | @@ -1969,7 +1999,7 @@ gr_check_create(const struct dentry * ne | |
88 | ||
89 | preempt_disable(); | |
90 | path = gr_to_filename_rbac(new_dentry, mnt); | |
91 | - match = lookup_name_entry(path); | |
92 | + match = lookup_name_entry_create(path); | |
93 | ||
94 | if (!match) | |
95 | goto check_parent; | |
96 | @@ -2334,7 +2364,7 @@ gr_set_proc_label(const struct dentry *d | |
97 | } | |
98 | ||
99 | static void | |
100 | -do_handle_delete(const ino_t ino, const dev_t dev) | |
101 | +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev) | |
102 | { | |
103 | struct acl_object_label *matchpo; | |
104 | struct acl_subject_label *matchps; | |
105 | @@ -2355,18 +2385,23 @@ do_handle_delete(const ino_t ino, const | |
106 | matchps->mode |= GR_DELETED; | |
107 | FOR_EACH_ROLE_END(role,i) | |
108 | ||
109 | + inodev->nentry->deleted = 1; | |
110 | + | |
111 | return; | |
112 | } | |
113 | ||
114 | void | |
115 | gr_handle_delete(const ino_t ino, const dev_t dev) | |
116 | { | |
117 | + struct inodev_entry *inodev; | |
118 | + | |
119 | if (unlikely(!(gr_status & GR_READY))) | |
120 | return; | |
121 | ||
122 | write_lock(&gr_inode_lock); | |
123 | - if (unlikely((unsigned long)lookup_inodev_entry(ino, dev))) | |
124 | - do_handle_delete(ino, dev); | |
125 | + inodev = lookup_inodev_entry(ino, dev); | |
126 | + if (inodev != NULL) | |
127 | + do_handle_delete(inodev, ino, dev); | |
128 | write_unlock(&gr_inode_lock); | |
129 | ||
130 | return; | |
131 | @@ -2460,11 +2495,12 @@ update_inodev_entry(const ino_t oldinode | |
132 | match = inodev_set.i_hash[index]; | |
133 | ||
134 | while (match && (match->nentry->inode != oldinode || | |
135 | - match->nentry->device != olddevice)) | |
136 | + match->nentry->device != olddevice || !match->nentry->deleted)) | |
137 | match = match->next; | |
138 | ||
139 | if (match && (match->nentry->inode == oldinode) | |
140 | - && (match->nentry->device == olddevice)) { | |
141 | + && (match->nentry->device == olddevice) && | |
142 | + match->nentry->deleted) { | |
143 | if (match->prev == NULL) { | |
144 | inodev_set.i_hash[index] = match->next; | |
145 | if (match->next != NULL) | |
146 | @@ -2478,6 +2514,7 @@ update_inodev_entry(const ino_t oldinode | |
147 | match->next = NULL; | |
148 | match->nentry->inode = newinode; | |
149 | match->nentry->device = newdevice; | |
150 | + match->nentry->deleted = 0; | |
151 | ||
152 | insert_inodev_entry(match); | |
153 | } | |
154 | @@ -2546,6 +2583,7 @@ gr_handle_rename(struct inode *old_dir, | |
155 | struct vfsmount *mnt, const __u8 replace) | |
156 | { | |
157 | struct name_entry *matchn; | |
158 | + struct inodev_entry *inodev; | |
159 | ||
160 | if (unlikely(!(gr_status & GR_READY))) | |
161 | return; | |
162 | @@ -2559,17 +2597,17 @@ gr_handle_rename(struct inode *old_dir, | |
163 | ||
164 | write_lock(&gr_inode_lock); | |
165 | if (unlikely(replace && new_dentry->d_inode)) { | |
166 | - if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino, | |
167 | - new_dentry->d_inode->i_sb->s_dev) && | |
168 | - (old_dentry->d_inode->i_nlink <= 1))) | |
169 | - do_handle_delete(new_dentry->d_inode->i_ino, | |
170 | + inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino, | |
171 | + new_dentry->d_inode->i_sb->s_dev); | |
172 | + if (inodev != NULL && (new_dentry->d_inode->i_nlink<= 1)) | |
173 | + do_handle_delete(inodev, new_dentry->d_inode->i_ino, | |
174 | new_dentry->d_inode->i_sb->s_dev); | |
175 | } | |
176 | ||
177 | - if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino, | |
178 | - old_dentry->d_inode->i_sb->s_dev) && | |
179 | - (old_dentry->d_inode->i_nlink <= 1))) | |
180 | - do_handle_delete(old_dentry->d_inode->i_ino, | |
181 | + inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino, | |
182 | + old_dentry->d_inode->i_sb->s_dev); | |
183 | + if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1)) | |
184 | + do_handle_delete(inodev, old_dentry->d_inode->i_ino, | |
185 | old_dentry->d_inode->i_sb->s_dev); | |
186 | ||
187 | if (unlikely((unsigned long)matchn)) | |
188 | diff -urp a/include/linux/gracl.h c/include/linux/gracl.h | |
189 | --- a/include/linux/gracl.h 2007-12-10 23:52:36.116497500 +0100 | |
190 | +++ c/include/linux/gracl.h 2007-12-11 00:31:52.947790250 +0100 | |
191 | @@ -52,6 +52,7 @@ struct name_entry { | |
192 | dev_t device; | |
193 | char *name; | |
194 | __u16 len; | |
195 | + __u8 deleted; | |
196 | struct name_entry *prev; | |
197 | struct name_entry *next; | |
198 | }; | |
199 | diff -upr a/grsecurity/gracl_cap.c c/grsecurity/gracl_cap.c | |
200 | --- a/grsecurity/gracl_cap.c 2007-12-01 00:54:57.312774500 +0000 | |
201 | +++ c/grsecurity/gracl_cap.c 2007-12-01 01:09:34.923621750 +0000 | |
202 | @@ -111,3 +111,10 @@ gr_is_capable_nolog(const int cap) | |
203 | return 0; | |
204 | } | |
205 | ||
206 | +void | |
207 | +gr_log_cap_x(const int cap) | |
208 | +{ | |
209 | + if (gr_acl_is_enabled()) | |
210 | + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, current, captab_log[cap]); | |
211 | + return; | |
212 | +} | |
213 | diff -upr a/grsecurity/grsec_sock.c c/grsecurity/grsec_sock.c | |
214 | --- a/grsecurity/grsec_sock.c 2007-12-01 00:54:57.316774750 +0000 | |
215 | +++ c/grsecurity/grsec_sock.c 2007-12-01 01:09:34.923621750 +0000 | |
216 | @@ -251,13 +251,24 @@ __u32 | |
217 | gr_cap_rtnetlink(void) | |
218 | { | |
219 | #ifdef CONFIG_GRKERNSEC | |
220 | + struct acl_subject_label *curracl; | |
221 | + __u32 cap_drop = 0, cap_mask = 0; | |
222 | + | |
223 | if (!gr_acl_is_enabled()) | |
224 | return current->cap_effective; | |
225 | - else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) && | |
226 | - gr_task_is_capable(current, CAP_NET_ADMIN)) | |
227 | - return current->cap_effective; | |
228 | - else | |
229 | - return 0; | |
230 | + else { | |
231 | + curracl = current->acl; | |
232 | + | |
233 | + cap_drop = curracl->cap_lower; | |
234 | + cap_mask = curracl->cap_mask; | |
235 | + | |
236 | + while ((curracl = curracl->parent_subject)) { | |
237 | + cap_drop |= curracl->cap_lower & \ | |
238 | + (cap_mask & ~curracl->cap_mask); | |
239 | + cap_mask |= curracl->cap_mask; | |
240 | + } | |
241 | + return (current->cap_effective & ~(cap_drop & cap_mask)); | |
242 | + } | |
243 | #else | |
244 | return current->cap_effective; | |
245 | #endif | |
246 | diff -upr a/include/linux/grsecurity.h c/include/linux/grsecurity.h | |
247 | --- a/include/linux/grsecurity.h 2007-12-01 00:54:57.224769000 +0000 | |
248 | +++ c/include/linux/grsecurity.h 2007-12-01 01:09:34.923621750 +0000 | |
249 | @@ -62,6 +62,7 @@ void gr_log_semrm(const uid_t uid, const | |
250 | void gr_log_shmget(const int err, const int shmflg, const size_t size); | |
251 | void gr_log_shmrm(const uid_t uid, const uid_t cuid); | |
252 | void gr_log_textrel(struct vm_area_struct *vma); | |
253 | +void gr_log_cap_x(const int cap); | |
254 | ||
255 | int gr_handle_follow_link(const struct inode *parent, | |
256 | const struct inode *inode, | |
257 | diff -upr a/security/commoncap.c c/security/commoncap.c | |
258 | --- a/security/commoncap.c 2007-12-01 00:54:57.300773750 +0000 | |
259 | +++ c/security/commoncap.c 2007-12-01 01:09:34.923621750 +0000 | |
b6142922 | 260 | @@ -35,8 +35,12 @@ |
8f71d8af | 261 | |
262 | int cap_netlink_recv(struct sk_buff *skb, int cap) | |
263 | { | |
264 | - if (!cap_raised(NETLINK_CB(skb).eff_cap, cap)) | |
265 | + if (!cap_raised(NETLINK_CB(skb).eff_cap, cap)) { | |
df741a01 | 266 | +#ifdef CONFIG_GRKERNSEC |
8f71d8af | 267 | + gr_log_cap_x(cap); |
df741a01 | 268 | +#endif |
8f71d8af | 269 | return -EPERM; |
270 | + } | |
271 | return 0; | |
272 | } | |
273 |