netlink no-stack-protector cap_dac* 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 @@ -110,3 +110,20 @@ gr_is_capable_nolog(const int cap) return 0; } +void +gr_log_cap_pid(const int cap, const pid_t pid) +{ + struct task_struct *p; + + if (gr_acl_is_enabled()) { + read_lock(&tasklist_lock); + p = find_task_by_pid(pid); + if (p) { + task_lock(p); + gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, p, captab_log[cap]); + task_unlock(p); + } + read_unlock(&tasklist_lock); + } + return; +} --- a/grsecurity/grsec_sock.c 2008-03-24 00:24:22.482633101 +0100 +++ c/grsecurity/grsec_sock.c 2008-03-24 00:27:01.971671763 +0100 @@ -251,23 +251,24 @@ __u32 gr_cap_rtnetlink(struct sock *sock) { #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 (sock->sk_protocol == NETLINK_ISCSI && - cap_raised(current->cap_effective, CAP_SYS_ADMIN) && - gr_task_is_capable(current, CAP_SYS_ADMIN)) - return current->cap_effective; - else if (sock->sk_protocol == NETLINK_AUDIT && - cap_raised(current->cap_effective, CAP_AUDIT_WRITE) && - gr_task_is_capable(current, CAP_AUDIT_WRITE) && - cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) && - gr_task_is_capable(current, CAP_AUDIT_CONTROL)) - 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 @@ -76,6 +76,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_pid(const int cap, pid_t pid); 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 @@ -55,8 +55,12 @@ 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)) { +#ifdef CONFIG_GRKERNSEC + gr_log_cap_pid(cap, NETLINK_CREDS(skb)->pid); +#endif return -EPERM; + } return 0; } === === cap_dac_ succession with capable_nolog === diff -upr a/fs./namei.c a/fs/namei.c --- a/fs./namei.c 2008-04-05 01:23:49.741310000 +0200 +++ a/fs/namei.c 2008-04-05 14:36:39.350275977 +0200 @@ -215,6 +215,13 @@ int generic_permission(struct inode *ino check_capabilities: /* + * Searching includes executable on directories, else just read. + */ + if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) + if (capable_nolog(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH)) + return 0; + + /* * Read/write DACs are always overridable. * Executable DACs are overridable if at least one exec bit is set. */ @@ -223,13 +230,6 @@ int generic_permission(struct inode *ino if (capable(CAP_DAC_OVERRIDE)) return 0; - /* - * Searching includes executable on directories, else just read. - */ - if (mask == MAY_READ || (S_ISDIR(inode->i_mode) && !(mask & MAY_WRITE))) - if (capable(CAP_DAC_READ_SEARCH)) - return 0; - return -EACCES; } @@ -498,13 +498,13 @@ static int exec_permission_lite(struct i if (mode & MAY_EXEC) goto ok; - if ((inode->i_mode & S_IXUGO) && capable(CAP_DAC_OVERRIDE)) + if (S_ISDIR(inode->i_mode) && capable_nolog(CAP_DAC_OVERRIDE)) goto ok; - if (S_ISDIR(inode->i_mode) && capable(CAP_DAC_OVERRIDE)) + if (S_ISDIR(inode->i_mode) && capable(CAP_DAC_READ_SEARCH)) goto ok; - if (S_ISDIR(inode->i_mode) && capable(CAP_DAC_READ_SEARCH)) + if ((inode->i_mode & S_IXUGO) && capable(CAP_DAC_OVERRIDE)) goto ok; return -EACCES; Tylko w fs: namei.c~ diff -upr a/fs./xfs/xfs_inode.c a/fs/xfs/xfs_inode.c --- a/fs./xfs/xfs_inode.c 2008-04-05 01:23:48.241413000 +0200 +++ a/fs/xfs/xfs_inode.c 2008-04-05 14:55:58.270625942 +0200 @@ -3663,20 +3663,16 @@ xfs_iaccess( * Read/write DACs are always overridable. * Executable DACs are overridable if at least one exec bit is set. */ + if ((orgmode == S_IRUSR) || + (S_ISDIR(inode->i_mode) && (!(orgmode & S_IWUSR)))) + if (capable_nolog(CAP_DAC_OVERRIDE) || capable_cred(cr, CAP_DAC_READ_SEARCH)) + return 0; + if (!(orgmode & S_IXUSR) || (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode)) if (capable_cred(cr, CAP_DAC_OVERRIDE)) return 0; - if ((orgmode == S_IRUSR) || - (S_ISDIR(inode->i_mode) && (!(orgmode & S_IWUSR)))) { - if (capable_cred(cr, CAP_DAC_READ_SEARCH)) - return 0; -#ifdef NOISE - cmn_err(CE_NOTE, "Ick: mode=%o, orgmode=%o", mode, orgmode); -#endif /* NOISE */ - return XFS_ERROR(EACCES); - } return XFS_ERROR(EACCES); } === === check if -fno-stack-protector is accessible === --- linux-2.6.24/arch/x86/kernel/Makefile_64~ 2008-04-16 21:15:48.278373002 +0000 +++ linux-2.6.24/arch/x86/kernel/Makefile_64 2008-04-16 21:18:33.833661431 +0000 @@ -42,6 +42,7 @@ obj-y += topology.o obj-y += pcspeaker.o -CFLAGS_vsyscall_64.o := $(PROFILING) -g0 -fno-stack-protector -CFLAGS_hpet.o := -fno-stack-protector -CFLAGS_tsc_64.o := -fno-stack-protector +nostackp := $(call cc-option, -fno-stack-protector) +CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) +CFLAGS_hpet.o := $(nostackp) +CFLAGS_tsc_64.o := $(nostackp)