]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-grsec_fixes.patch
- windows mobile 5 support
[packages/kernel.git] / kernel-grsec_fixes.patch
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
260 @@ -35,8 +35,10 @@ EXPORT_SYMBOL(cap_netlink_send);
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)) {
266 +               gr_log_cap_x(cap);
267                 return -EPERM;
268 +       }
269         return 0;
270  }
271  
This page took 0.094486 seconds and 3 git commands to generate.