SOURCES (LINUX_2_6_22): kernel-grsec_fixes.patch (NEW) - fixes fro...
zbyniu
zbyniu at pld-linux.org
Wed Dec 12 13:21:15 CET 2007
Author: zbyniu Date: Wed Dec 12 12:21:15 2007 GMT
Module: SOURCES Tag: LINUX_2_6_22
---- Log message:
- fixes from current and future releases
---- Files affected:
SOURCES:
kernel-grsec_fixes.patch (NONE -> 1.1.2.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/kernel-grsec_fixes.patch
diff -u /dev/null SOURCES/kernel-grsec_fixes.patch:1.1.2.1
--- /dev/null Wed Dec 12 13:21:15 2007
+++ SOURCES/kernel-grsec_fixes.patch Wed Dec 12 13:21:10 2007
@@ -0,0 +1,271 @@
+audits
+rename
+netlink
+diff -urp a/grsecurity/gracl.c c/grsecurity/gracl.c
+--- a/grsecurity/gracl.c 2007-12-10 23:52:36.040492750 +0100
++++ c/grsecurity/gracl.c 2007-12-11 00:32:38.094611750 +0100
+@@ -329,7 +329,7 @@ to_gr_audit(const __u32 reqmode)
+ /* masks off auditable permission flags, then shifts them to create
+ auditing flags, and adds the special case of append auditing if
+ we're requesting write */
+- return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
++ return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
+ }
+
+ struct acl_subject_label *
+@@ -519,6 +519,35 @@ lookup_name_entry(const char *name)
+ return match;
+ }
+
++static struct name_entry *
++lookup_name_entry_create(const char *name)
++{
++ unsigned int len = strlen(name);
++ unsigned int key = full_name_hash(name, len);
++ unsigned int index = key % name_set.n_size;
++ struct name_entry *match;
++
++ match = name_set.n_hash[index];
++
++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
++ !match->deleted))
++ match = match->next;
++
++ if (match && match->deleted)
++ return match;
++
++ match = name_set.n_hash[index];
++
++ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
++ match->deleted))
++ match = match->next;
++
++ if (match && !match->deleted)
++ return match;
++ else
++ return NULL;
++}
++
+ static struct inodev_entry *
+ lookup_inodev_entry(const ino_t ino, const dev_t dev)
+ {
+@@ -584,7 +613,7 @@ insert_acl_role_label(struct acl_role_la
+ }
+
+ static int
+-insert_name_entry(char *name, const ino_t inode, const dev_t device)
++insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
+ {
+ struct name_entry **curr, *nentry;
+ struct inodev_entry *ientry;
+@@ -613,6 +642,7 @@ insert_name_entry(char *name, const ino_
+ nentry->inode = inode;
+ nentry->device = device;
+ nentry->len = len;
++ nentry->deleted = deleted;
+
+ nentry->prev = NULL;
+ curr = &name_set.n_hash[index];
+@@ -975,7 +1005,7 @@ copy_user_objs(struct acl_object_label *
+
+ insert_acl_obj_label(o_tmp, subj);
+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
+- o_tmp->device))
++ o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
+ return -ENOMEM;
+
+ ret = copy_user_glob(o_tmp);
+@@ -1270,7 +1300,7 @@ do_copy_user_subj(struct acl_subject_lab
+
+ insert:
+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
+- s_tmp->device))
++ s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
+ return ERR_PTR(-ENOMEM);
+
+ return s_tmp;
+@@ -1969,7 +1999,7 @@ gr_check_create(const struct dentry * ne
+
+ preempt_disable();
+ path = gr_to_filename_rbac(new_dentry, mnt);
+- match = lookup_name_entry(path);
++ match = lookup_name_entry_create(path);
+
+ if (!match)
+ goto check_parent;
+@@ -2334,7 +2364,7 @@ gr_set_proc_label(const struct dentry *d
+ }
+
+ static void
+-do_handle_delete(const ino_t ino, const dev_t dev)
++do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
+ {
+ struct acl_object_label *matchpo;
+ struct acl_subject_label *matchps;
+@@ -2355,18 +2385,23 @@ do_handle_delete(const ino_t ino, const
+ matchps->mode |= GR_DELETED;
+ FOR_EACH_ROLE_END(role,i)
+
++ inodev->nentry->deleted = 1;
++
+ return;
+ }
+
+ void
+ gr_handle_delete(const ino_t ino, const dev_t dev)
+ {
++ struct inodev_entry *inodev;
++
+ if (unlikely(!(gr_status & GR_READY)))
+ return;
+
+ write_lock(&gr_inode_lock);
+- if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
+- do_handle_delete(ino, dev);
++ inodev = lookup_inodev_entry(ino, dev);
++ if (inodev != NULL)
++ do_handle_delete(inodev, ino, dev);
+ write_unlock(&gr_inode_lock);
+
+ return;
+@@ -2460,11 +2495,12 @@ update_inodev_entry(const ino_t oldinode
+ match = inodev_set.i_hash[index];
+
+ while (match && (match->nentry->inode != oldinode ||
+- match->nentry->device != olddevice))
++ match->nentry->device != olddevice || !match->nentry->deleted))
+ match = match->next;
+
+ if (match && (match->nentry->inode == oldinode)
+- && (match->nentry->device == olddevice)) {
++ && (match->nentry->device == olddevice) &&
++ match->nentry->deleted) {
+ if (match->prev == NULL) {
+ inodev_set.i_hash[index] = match->next;
+ if (match->next != NULL)
+@@ -2478,6 +2514,7 @@ update_inodev_entry(const ino_t oldinode
+ match->next = NULL;
+ match->nentry->inode = newinode;
+ match->nentry->device = newdevice;
++ match->nentry->deleted = 0;
+
+ insert_inodev_entry(match);
+ }
+@@ -2546,6 +2583,7 @@ gr_handle_rename(struct inode *old_dir,
+ struct vfsmount *mnt, const __u8 replace)
+ {
+ struct name_entry *matchn;
++ struct inodev_entry *inodev;
+
+ if (unlikely(!(gr_status & GR_READY)))
+ return;
+@@ -2559,17 +2597,17 @@ gr_handle_rename(struct inode *old_dir,
+
+ write_lock(&gr_inode_lock);
+ if (unlikely(replace && new_dentry->d_inode)) {
+- if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
+- new_dentry->d_inode->i_sb->s_dev) &&
+- (old_dentry->d_inode->i_nlink <= 1)))
+- do_handle_delete(new_dentry->d_inode->i_ino,
++ inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
++ new_dentry->d_inode->i_sb->s_dev);
++ if (inodev != NULL && (new_dentry->d_inode->i_nlink<= 1))
++ do_handle_delete(inodev, new_dentry->d_inode->i_ino,
+ new_dentry->d_inode->i_sb->s_dev);
+ }
+
+- if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
+- old_dentry->d_inode->i_sb->s_dev) &&
+- (old_dentry->d_inode->i_nlink <= 1)))
+- do_handle_delete(old_dentry->d_inode->i_ino,
++ inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
++ old_dentry->d_inode->i_sb->s_dev);
++ if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
++ do_handle_delete(inodev, old_dentry->d_inode->i_ino,
+ old_dentry->d_inode->i_sb->s_dev);
+
+ if (unlikely((unsigned long)matchn))
+diff -urp a/include/linux/gracl.h c/include/linux/gracl.h
+--- a/include/linux/gracl.h 2007-12-10 23:52:36.116497500 +0100
++++ c/include/linux/gracl.h 2007-12-11 00:31:52.947790250 +0100
+@@ -52,6 +52,7 @@ struct name_entry {
+ dev_t device;
+ char *name;
+ __u16 len;
++ __u8 deleted;
+ struct name_entry *prev;
+ struct name_entry *next;
+ };
+diff -upr a/grsecurity/gracl_cap.c c/grsecurity/gracl_cap.c
+--- a/grsecurity/gracl_cap.c 2007-12-01 00:54:57.312774500 +0000
++++ c/grsecurity/gracl_cap.c 2007-12-01 01:09:34.923621750 +0000
+@@ -111,3 +111,10 @@ gr_is_capable_nolog(const int cap)
+ return 0;
+ }
+
++void
++gr_log_cap_x(const int cap)
++{
++ if (gr_acl_is_enabled())
++ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, current, captab_log[cap]);
++ return;
++}
+diff -upr a/grsecurity/grsec_sock.c c/grsecurity/grsec_sock.c
+--- a/grsecurity/grsec_sock.c 2007-12-01 00:54:57.316774750 +0000
++++ c/grsecurity/grsec_sock.c 2007-12-01 01:09:34.923621750 +0000
+@@ -251,13 +251,24 @@ __u32
+ gr_cap_rtnetlink(void)
+ {
+ #ifdef CONFIG_GRKERNSEC
++ struct acl_subject_label *curracl;
++ __u32 cap_drop = 0, cap_mask = 0;
++
+ if (!gr_acl_is_enabled())
+ return current->cap_effective;
+- else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
+- gr_task_is_capable(current, CAP_NET_ADMIN))
+- return current->cap_effective;
+- else
+- return 0;
++ else {
++ curracl = current->acl;
++
++ cap_drop = curracl->cap_lower;
++ cap_mask = curracl->cap_mask;
++
++ while ((curracl = curracl->parent_subject)) {
++ cap_drop |= curracl->cap_lower & \
++ (cap_mask & ~curracl->cap_mask);
++ cap_mask |= curracl->cap_mask;
++ }
++ return (current->cap_effective & ~(cap_drop & cap_mask));
++ }
+ #else
+ return current->cap_effective;
+ #endif
+diff -upr a/include/linux/grsecurity.h c/include/linux/grsecurity.h
+--- a/include/linux/grsecurity.h 2007-12-01 00:54:57.224769000 +0000
++++ c/include/linux/grsecurity.h 2007-12-01 01:09:34.923621750 +0000
+@@ -62,6 +62,7 @@ void gr_log_semrm(const uid_t uid, const
+ void gr_log_shmget(const int err, const int shmflg, const size_t size);
+ void gr_log_shmrm(const uid_t uid, const uid_t cuid);
+ void gr_log_textrel(struct vm_area_struct *vma);
++void gr_log_cap_x(const int cap);
+
+ int gr_handle_follow_link(const struct inode *parent,
+ const struct inode *inode,
+diff -upr a/security/commoncap.c c/security/commoncap.c
+--- a/security/commoncap.c 2007-12-01 00:54:57.300773750 +0000
++++ c/security/commoncap.c 2007-12-01 01:09:34.923621750 +0000
+@@ -35,8 +35,10 @@ EXPORT_SYMBOL(cap_netlink_send);
+
+ int cap_netlink_recv(struct sk_buff *skb, int cap)
+ {
+- if (!cap_raised(NETLINK_CB(skb).eff_cap, cap))
++ if (!cap_raised(NETLINK_CB(skb).eff_cap, cap)) {
++ gr_log_cap_x(cap);
+ return -EPERM;
++ }
+ return 0;
+ }
+
================================================================
More information about the pld-cvs-commit
mailing list