diff -urN linux-2.4.22/Documentation/Configure.help linux-2.4.22-grsec/Documentation/Configure.help --- linux-2.4.22/Documentation/Configure.help 2003-10-09 18:47:38.000000000 +0200 +++ linux-2.4.22-grsec/Documentation/Configure.help 2003-10-09 19:13:26.000000000 +0200 @@ -2977,6 +2977,20 @@ If you want to compile it as a module, say M here and read Documentation/modules.txt. If unsure, say `N'. +stealth networking support +CONFIG_IP_NF_MATCH_STEALTH + Enabling this option will drop all syn packets coming to unserved tcp + ports as well as all packets coming to unserved udp ports. If you + are using your system to route any type of packets (ie. via NAT) + you should put this module at the end of your ruleset, since it will + drop packets that aren't going to ports that are listening on your + machine itself, it doesn't take into account that the packet might be + destined for someone on your internal network if you're using NAT for + instance. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + MAC address match support CONFIG_IP_NF_MATCH_MAC MAC matching allows you to match packets based on the source @@ -23554,6 +23568,233 @@ "Area6" will work for most boards. For ADX, select "Area5". +Grsecurity +CONFIG_GRKERNSEC + If you say Y here, you will be able to configure many features that + will enhance the security of your system. It is highly recommended + that you say Y here and read through the help for each option so + you fully understand the features and can evaluate their usefulness + for your machine. + +/proc//ipaddr support +CONFIG_GRKERNSEC_PROC_IPADDR + If you say Y here, a new entry will be added to each /proc/ + directory that contains the IP address of the person using the task. + The IP is carried across local TCP and AF_UNIX stream sockets. + This information can be useful for IDS/IPSes to perform remote response + to a local attack. The entry is readable by only the owner of the + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via + the RBAC system), and thus does not create privacy concerns. + +Deny access to abstract AF_UNIX sockets out of chroot +CONFIG_GRKERNSEC_CHROOT_UNIX + If you say Y here, processes inside a chroot will not be able to + connect to abstract (meaning not belonging to a filesystem) Unix + domain sockets that were bound outside of a chroot. It is recommended + that you say Y here. If the sysctl option is enabled, a sysctl option + with name "chroot_deny_unix" is created. + +Deny shmat() out of chroot +CONFIG_GRKERNSEC_CHROOT_SHMAT + If you say Y here, processes inside a chroot will not be able to attach + to shared memory segments that were created outside of the chroot jail. + It is recommended that you say Y here. If the sysctl option is enabled, + a sysctl option with name "chroot_deny_shmat" is created. + +Protect outside processes +CONFIG_GRKERNSEC_CHROOT_FINDTASK + If you say Y here, processes inside a chroot will not be able to + kill, send signals with fcntl, ptrace, capget, setpgid, getpgid, + getsid, or view any process outside of the chroot. If the sysctl + option is enabled, a sysctl option with name "chroot_findtask" is + created. + +Deny mounts in chroot +CONFIG_GRKERNSEC_CHROOT_MOUNT + If you say Y here, processes inside a chroot will not be able to + mount or remount filesystems. If the sysctl option is enabled, a + sysctl option with name "chroot_deny_mount" is created. + +Deny pivot_root in chroot +CONFIG_GRKERNSEC_CHROOT_PIVOT + If you say Y here, processes inside a chroot will not be able to use + a function called pivot_root() that was introduced in Linux 2.3.41. It + works similar to chroot in that it changes the root filesystem. This + function could be misused in a chrooted process to attempt to break out + of the chroot, and therefore should not be allowed. If the sysctl + option is enabled, a sysctl option with name "chroot_deny_pivot" is + created. + +Deny double-chroots +CONFIG_GRKERNSEC_CHROOT_DOUBLE + If you say Y here, processes inside a chroot will not be able to chroot + again. This is a widely used method of breaking out of a chroot jail + and should not be allowed. If the sysctl option is enabled, a sysctl + option with name "chroot_deny_chroot" is created. + +Deny fchdir outside of chroot +CONFIG_GRKERNSEC_CHROOT_FCHDIR + If you say Y here, a well-known method of breaking chroots by fchdir'ing + to a file descriptor of the chrooting process that points to a directory + outside the filesystem will be stopped. If the sysctl option + is enabled, a sysctl option with name "chroot_deny_fchdir" is created. + +Enforce chdir("/") on all chroots +CONFIG_GRKERNSEC_CHROOT_CHDIR + If you say Y here, the current working directory of all newly-chrooted + applications will be set to the the root directory of the chroot. + The man page on chroot(2) states: + Note that this call does not change the current working + directory, so that `.' can be outside the tree rooted at + `/'. In particular, the super-user can escape from a + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'. + + It is recommended that you say Y here, since it's not known to break + any software. If the sysctl option is enabled, a sysctl option with + name "chroot_enforce_chdir" is created. + +Deny (f)chmod +s in chroot +CONFIG_GRKERNSEC_CHROOT_CHMOD + If you say Y here, processes inside a chroot will not be able to chmod + or fchmod files to make them have suid or sgid bits. This protects + against another published method of breaking a chroot. If the sysctl + option is enabled, a sysctl option with name "chroot_deny_chmod" is + created. + +Deny mknod in chroot +CONFIG_GRKERNSEC_CHROOT_MKNOD + If you say Y here, processes inside a chroot will not be allowed to + mknod. The problem with using mknod inside a chroot is that it + would allow an attacker to create a device entry that is the same + as one on the physical root of your system, which could range from + anything from the console device to a device for your harddrive (which + they could then use to wipe the drive or steal data). It is recommended + that you say Y here, unless you run into software incompatibilities. + If the sysctl option is enabled, a sysctl option with name + "chroot_deny_mknod" is created. + +Restrict priority changes in chroot +CONFIG_GRKERNSEC_CHROOT_NICE + If you say Y here, processes inside a chroot will not be able to raise + the priority of processes in the chroot, or alter the priority of + processes outside the chroot. This provides more security than simply + removing CAP_SYS_NICE from the process' capability set. If the + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice" + is created. + +Log all execs within chroot +CONFIG_GRKERNSEC_CHROOT_EXECLOG + If you say Y here, all executions inside a chroot jail will be logged + to syslog. This can cause a large amount of logs if certain + applications (eg. djb's daemontools) are installed on the system, and + is therefore left as an option. If the sysctl option is enabled, a + sysctl option with name "chroot_execlog" is created. + +Deny sysctl writes in chroot +CONFIG_GRKERNSEC_CHROOT_SYSCTL + If you say Y here, an attacker in a chroot will not be able to + write to sysctl entries, either by sysctl(2) or through a /proc + interface. It is strongly recommended that you say Y here. If the + sysctl option is enabled, a sysctl option with name + "chroot_deny_sysctl" is created. + +Chroot jail capability restrictions +CONFIG_GRKERNSEC_CHROOT_CAPS + If you say Y here, the capabilities on all root processes within a + chroot jail will be lowered to stop module insertion, raw i/o, + system and net admin tasks, rebooting the system, modifying immutable + files, modifying IPC owned by another, and changing the system time. + This is left an option because it can break some apps. Disable this + if your chrooted apps are having problems performing those kinds of + tasks. If the sysctl option is enabled, a sysctl option with + name "chroot_caps" is created. + +Trusted path execution +CONFIG_GRKERNSEC_TPE + If you say Y here, you will be able to choose a gid to add to the + supplementary groups of users you want to mark as "untrusted." + These users will not be able to execute any files that are not in + root-owned directories writable only by root. If the sysctl option + is enabled, a sysctl option with name "tpe" is created. + +Group for trusted path execution +CONFIG_GRKERNSEC_TPE_GID + Here you can choose the GID to enable trusted path protection for. + Remember to add the users you want protection enabled for to the GID + specified here. If the sysctl option is enabled, whatever you choose + here won't matter. You'll have to specify the GID in your bootup + script by echoing the GID to the proper /proc entry. View the help + on the sysctl option for more information. If the sysctl option is + enabled, a sysctl option with name "tpe_gid" is created. + +Partially restrict non-root users +CONFIG_GRKERNSEC_TPE_ALL + If you say Y here, All non-root users other than the ones in the + group specified in the main TPE option will only be allowed to + execute files in directories they own that are not group or + world-writable, or in directories owned by root and writable only by + root. If the sysctl option is enabled, a sysctl option with name + "tpe_restrict_all" is created. + +Socket restrictions +CONFIG_GRKERNSEC_SOCKET + If you say Y here, you will be able to choose from several options. + If you assign a GID on your system and add it to the supplementary + groups of users you want to restrict socket access to, this patch + will perform up to three things, based on the option(s) you choose. + +Deny all socket access +CONFIG_GRKERNSEC_SOCKET_ALL + If you say Y here, you will be able to choose a GID of whose users will + be unable to connect to other hosts from your machine or run server + applications from your machine. If the sysctl option is enabled, a + sysctl option with name "socket_all" is created. + +Group for disabled socket access +CONFIG_GRKERNSEC_SOCKET_ALL_GID + Here you can choose the GID to disable socket access for. Remember to + add the users you want socket access disabled for to the GID + specified here. If the sysctl option is enabled, whatever you choose + here won't matter. You'll have to specify the GID in your bootup + script by echoing the GID to the proper /proc entry. View the help + on the sysctl option for more information. If the sysctl option is + enabled, a sysctl option with name "socket_all_gid" is created. + +Deny all client socket access +CONFIG_GRKERNSEC_SOCKET_CLIENT + If you say Y here, you will be able to choose a GID of whose users will + be unable to connect to other hosts from your machine, but will be + able to run servers. If this option is enabled, all users in the group + you specify will have to use passive mode when initiating ftp transfers + from the shell on your machine. If the sysctl option is enabled, a + sysctl option with name "socket_client" is created. + +Group for disabled client socket access +CONFIG_GRKERNSEC_SOCKET_CLIENT_GID + Here you can choose the GID to disable client socket access for. + Remember to add the users you want client socket access disabled for to + the GID specified here. If the sysctl option is enabled, whatever you + choose here won't matter. You'll have to specify the GID in your bootup + script by echoing the GID to the proper /proc entry. View the help + on the sysctl option for more information. If the sysctl option is + enabled, a sysctl option with name "socket_client_gid" is created. + +Deny all server socket access +CONFIG_GRKERNSEC_SOCKET_SERVER + If you say Y here, you will be able to choose a GID of whose users will + be unable to run server applications from your machine. If the sysctl + option is enabled, a sysctl option with name "socket_server" is created. + +Group for disabled server socket access +CONFIG_GRKERNSEC_SOCKET_SERVER_GID + Here you can choose the GID to disable server socket access for. + Remember to add the users you want server socket access disabled for to + the GID specified here. If the sysctl option is enabled, whatever you + choose here won't matter. You'll have to specify the GID in your bootup + script by echoing the GID to the proper /proc entry. View the help + on the sysctl option for more information. If the sysctl option is + enabled, a sysctl option with name "socket_server_gid" is created. + Disable data cache CONFIG_DCACHE_DISABLE This option allows you to run the kernel with data cache disabled. diff -urN linux-2.4.22/Makefile linux-2.4.22-grsec/Makefile --- linux-2.4.22/Makefile 2003-10-09 18:47:38.000000000 +0200 +++ linux-2.4.22-grsec/Makefile 2003-10-09 19:13:26.000000000 +0200 @@ -134,9 +134,10 @@ CORE_FILES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o NETWORKS =net/network.o +GRSECURITY =grsecurity/grsec.o LIBS =$(TOPDIR)/lib/lib.a -SUBDIRS =kernel drivers mm fs net ipc lib crypto +SUBDIRS =kernel drivers mm fs net ipc lib crypto grsecurity DRIVERS-n := DRIVERS-y := @@ -279,7 +280,7 @@ export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL -export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS +export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS GRSECURITY .S.s: $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $< @@ -298,6 +299,7 @@ $(CORE_FILES) \ $(DRIVERS) \ $(NETWORKS) \ + $(GRSECURITY) \ $(LIBS) \ --end-group \ -o vmlinux diff -urN linux-2.4.22/arch/alpha/config.in linux-2.4.22-grsec/arch/alpha/config.in --- linux-2.4.22/arch/alpha/config.in 2003-08-25 13:44:39.000000000 +0200 +++ linux-2.4.22-grsec/arch/alpha/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -457,3 +457,12 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu + diff -urN linux-2.4.22/arch/arm/config.in linux-2.4.22-grsec/arch/arm/config.in --- linux-2.4.22/arch/arm/config.in 2003-08-25 13:44:39.000000000 +0200 +++ linux-2.4.22-grsec/arch/arm/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -734,3 +734,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/cris/config.in linux-2.4.22-grsec/arch/cris/config.in --- linux-2.4.22/arch/cris/config.in 2003-08-25 13:44:39.000000000 +0200 +++ linux-2.4.22-grsec/arch/cris/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -275,3 +275,12 @@ source crypto/Config.in source lib/Config.in endmenu + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu + diff -urN linux-2.4.22/arch/i386/config.in linux-2.4.22-grsec/arch/i386/config.in --- linux-2.4.22/arch/i386/config.in 2003-10-09 18:47:37.000000000 +0200 +++ linux-2.4.22-grsec/arch/i386/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -502,3 +502,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/ia64/config.in linux-2.4.22-grsec/arch/ia64/config.in --- linux-2.4.22/arch/ia64/config.in 2003-08-25 13:44:39.000000000 +0200 +++ linux-2.4.22-grsec/arch/ia64/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -291,3 +291,12 @@ fi endmenu + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu + diff -urN linux-2.4.22/arch/m68k/config.in linux-2.4.22-grsec/arch/m68k/config.in --- linux-2.4.22/arch/m68k/config.in 2003-08-25 13:44:39.000000000 +0200 +++ linux-2.4.22-grsec/arch/m68k/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -564,3 +564,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/mips/config.in linux-2.4.22-grsec/arch/mips/config.in --- linux-2.4.22/arch/mips/config.in 2002-11-29 00:53:09.000000000 +0100 +++ linux-2.4.22-grsec/arch/mips/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -7,3 +7,11 @@ define_bool CONFIG_MIPS64 n source arch/mips/config-shared.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/mips64/config.in linux-2.4.22-grsec/arch/mips64/config.in --- linux-2.4.22/arch/mips64/config.in 2002-11-29 00:53:10.000000000 +0100 +++ linux-2.4.22-grsec/arch/mips64/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -7,3 +7,11 @@ define_bool CONFIG_MIPS64 y source arch/mips/config-shared.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/parisc/config.in linux-2.4.22-grsec/arch/parisc/config.in --- linux-2.4.22/arch/parisc/config.in 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.22-grsec/arch/parisc/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -198,3 +198,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/parisc/kernel/sys_parisc32.c linux-2.4.22/arch/parisc/kernel/sys_parisc32.c --- linux-2.4.22/arch/parisc/kernel/sys_parisc32.c 2003-09-01 22:19:44.000000000 -0400 +++ linux-2.4.22/arch/parisc/kernel/sys_parisc32.c 2003-09-02 19:29:41.000000000 -0400 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -177,6 +178,9 @@ struct file *file; int retval; int i; +#ifdef CONFIG_GRKERNSEC + struct file *old_exec_file; +#endif file = open_exec(filename); @@ -209,6 +234,13 @@ if (retval < 0) goto out; +#ifdef CONFIG_GRKERNSEC + if (!gr_tpe_allow(file)) { + retval = -EACCES; + goto out; + } +#endif + retval = copy_strings_kernel(1, &bprm.filename, &bprm); if (retval < 0) goto out; @@ -222,11 +260,26 @@ if (retval < 0) goto out; +#ifdef CONFIG_GRKERNSEC + old_exec_file = current->exec_file; + get_file(file); + current->exec_file = file; +#endif + retval = search_binary_handler(&bprm,regs); - if (retval >= 0) + if (retval >= 0) { +#ifdef CONFIG_GRKERNSEC + if (old_exec_file) + fput(old_exec_file); +#endif /* execve success */ return retval; + } +#ifdef CONFIG_GRKERNSEC + fput(current->exec_file); + current->exec_file = old_exec_file; +#endif out: /* Something went wrong, return the inode and free the argument pages*/ allow_write_access(bprm.file); diff -urN linux-2.4.22/arch/ppc/config.in linux-2.4.22-grsec/arch/ppc/config.in --- linux-2.4.22/arch/ppc/config.in 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.22-grsec/arch/ppc/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -488,3 +488,12 @@ bool 'Support for early boot texts over serial port' CONFIG_SERIAL_TEXT_DEBUG fi endmenu + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu + diff -urN linux-2.4.22/arch/s390/config.in linux-2.4.22-grsec/arch/s390/config.in --- linux-2.4.22/arch/s390/config.in 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.22-grsec/arch/s390/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -81,3 +81,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/s390x/config.in linux-2.4.22-grsec/arch/s390x/config.in --- linux-2.4.22/arch/s390x/config.in 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.22-grsec/arch/s390x/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -85,3 +85,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/sh/config.in linux-2.4.22-grsec/arch/sh/config.in --- linux-2.4.22/arch/sh/config.in 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.22-grsec/arch/sh/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -469,3 +469,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/sparc/boot/Makefile linux-2.4.22-grsec/arch/sparc/boot/Makefile --- linux-2.4.22/arch/sparc/boot/Makefile 2002-08-03 02:39:43.000000000 +0200 +++ linux-2.4.22-grsec/arch/sparc/boot/Makefile 2003-10-09 19:13:26.000000000 +0200 @@ -24,7 +24,7 @@ BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \ - $(DRIVERS) $(NETWORKS) + $(DRIVERS) $(NETWORKS) $(GRSECURITY) # I wanted to make this depend upon BTOBJS so that a parallel # build would work, but this fails because $(HEAD) cannot work diff -urN linux-2.4.22/arch/sparc/config.in linux-2.4.22-grsec/arch/sparc/config.in --- linux-2.4.22/arch/sparc/config.in 2003-08-25 13:44:40.000000000 +0200 +++ linux-2.4.22-grsec/arch/sparc/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -277,3 +277,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/sparc64/config.in linux-2.4.22-grsec/arch/sparc64/config.in --- linux-2.4.22/arch/sparc64/config.in 2003-10-09 18:47:24.000000000 +0200 +++ linux-2.4.22-grsec/arch/sparc64/config.in 2003-10-09 19:13:26.000000000 +0200 @@ -312,3 +312,11 @@ source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urN linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c --- linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c 2003-09-01 22:19:37.000000000 -0400 +++ linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c 2003-09-02 19:29:41.000000000 -0400 @@ -52,6 +52,8 @@ #include #include #include +#include +#include #include #include @@ -3233,6 +3235,9 @@ struct file * file; int retval; int i; +#ifdef CONFIG_GRKERNSEC + struct file *old_exec_file; +#endif bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0])); @@ -3263,6 +3289,13 @@ if (retval < 0) goto out; +#ifdef CONFIG_GRKERNSEC + if(!gr_tpe_allow(file)) { + retval = -EACCES; + goto out; + } +#endif + retval = copy_strings_kernel(1, &bprm.filename, &bprm); if (retval < 0) goto out; @@ -3276,11 +3315,26 @@ if (retval < 0) goto out; +#ifdef CONFIG_GRKERNSEC + old_exec_file = current->exec_file; + get_file(file); + current->exec_file = file; +#endif + retval = search_binary_handler(&bprm, regs); - if (retval >= 0) + if (retval >= 0) { +#ifdef CONFIG_GRKERNSEC + if (old_exec_file) + fput(old_exec_file); +#endif /* execve success */ return retval; + } +#ifdef CONFIG_GRKERNSEC + fput(current->exec_file); + current->exec_file = old_exec_file; +#endif out: /* Something went wrong, return the inode and free the argument pages*/ allow_write_access(bprm.file); diff -urN linux-2.4.22/fs/exec.c linux-2.4.22-grsec/fs/exec.c --- linux-2.4.22/fs/exec.c 2003-10-09 18:47:38.000000000 +0200 +++ linux-2.4.22-grsec/fs/exec.c 2003-10-09 19:13:26.000000000 +0200 @@ -43,6 +43,9 @@ #include #include #include +#include +#include +#include #ifdef CONFIG_KMOD #include @@ -780,6 +783,10 @@ current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; +#ifdef CONFIG_GRKERNSEC + gr_handle_chroot_caps(current); +#endif + if(do_unlock) unlock_kernel(); current->keep_capabilities = 0; @@ -907,6 +944,9 @@ struct file *file; int retval; int i; +#ifdef CONFIG_GRKERNSEC + struct file *old_exec_file; +#endif file = open_exec(filename); @@ -938,6 +999,13 @@ if (retval < 0) goto out; +#ifdef CONFIG_GRKERNSEC + if (!gr_tpe_allow(file)) { + retval = -EACCES; + goto out; + } +#endif + retval = copy_strings_kernel(1, &bprm.filename, &bprm); if (retval < 0) goto out; @@ -949,6 +954,11 @@ goto out; bprm.exec = bprm.p; + +#ifdef CONFIG_GRKERNSEC + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); +#endif + retval = copy_strings(bprm.envc, envp, &bprm); if (retval < 0) goto out; @@ -951,11 +1027,26 @@ if (retval < 0) goto out; +#ifdef CONFIG_GRKERNSEC + old_exec_file = current->exec_file; + get_file(file); + current->exec_file = file; +#endif + retval = search_binary_handler(&bprm,regs); - if (retval >= 0) + if (retval >= 0) { +#ifdef CONFIG_GRKERNSEC + if (old_exec_file) + fput(old_exec_file); +#endif /* execve success */ return retval; + } +#ifdef CONFIG_GRKERNSEC + fput(current->exec_file); + current->exec_file = old_exec_file; +#endif out: /* Something went wrong, return the inode and free the argument pages*/ allow_write_access(bprm.file); diff -urN linux-2.4.22/fs/fcntl.c linux-2.4.22-grsec/fs/fcntl.c --- linux-2.4.22/fs/fcntl.c 2002-11-29 00:53:15.000000000 +0100 +++ linux-2.4.22-grsec/fs/fcntl.c 2003-10-09 19:13:26.000000000 +0200 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -448,6 +449,10 @@ match = -p->pgrp; if (pid != match) continue; +#ifdef CONFIG_GRKERNSEC + if (gr_pid_is_chrooted(p)) + continue; +#endif send_sigio_to_task(p, fown, fd, band); } out: diff -urN linux-2.4.22/fs/namei.c linux-2.4.22-grsec/fs/namei.c --- linux-2.4.22/fs/namei.c 2003-10-09 18:47:32.000000000 +0200 +++ linux-2.4.22-grsec/fs/namei.c 2003-10-09 19:13:26.000000000 +0200 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -1284,6 +1285,14 @@ if (!IS_POSIXACL(nd.dentry->d_inode)) mode &= ~current->fs->umask; if (!IS_ERR(dentry)) { +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) { + error = -EPERM; + dput(dentry); + goto out_dput; + } +#endif + switch (mode & S_IFMT) { case 0: case S_IFREG: error = vfs_create(nd.dentry->d_inode,dentry,mode); @@ -1295,6 +1370,7 @@ } dput(dentry); } +out_dput: up(&nd.dentry->d_inode->i_sem); path_release(&nd); out: diff -urN linux-2.4.22/fs/namespace.c linux-2.4.22-grsec/fs/namespace.c --- linux-2.4.22/fs/namespace.c 2003-06-13 16:51:37.000000000 +0200 +++ linux-2.4.22-grsec/fs/namespace.c 2003-10-09 19:13:26.000000000 +0200 @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include @@ -729,6 +731,14 @@ if (retval) return retval; +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) { + retval = -EPERM; + path_release(&nd); + return retval; + } +#endif + if (flags & MS_REMOUNT) retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, data_page); @@ -909,6 +917,11 @@ if (!capable(CAP_SYS_ADMIN)) return -EPERM; +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_pivot()) + return -EPERM; +#endif + lock_kernel(); error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd); diff -urN linux-2.4.22/fs/open.c linux-2.4.22-grsec/fs/open.c --- linux-2.4.22/fs/open.c 2003-08-25 13:44:43.000000000 +0200 +++ linux-2.4.22-grsec/fs/open.c 2003-10-09 19:13:26.000000000 +0200 @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -426,6 +427,12 @@ goto out_putf; error = permission(inode, MAY_EXEC); + +#ifdef CONFIG_GRKERNSEC + if (!error && !gr_chroot_fchdir(dentry, mnt)) + error = -EPERM; +#endif + if (!error) set_fs_pwd(current->fs, mnt, dentry); out_putf: @@ -452,8 +457,20 @@ if (!capable(CAP_SYS_CHROOT)) goto dput_and_out; +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_chroot(nd.dentry, nd.mnt)) + goto dput_and_out; +#endif + set_fs_root(current->fs, nd.mnt, nd.dentry); set_fs_altroot(); + +#ifdef CONFIG_GRKERNSEC + gr_handle_chroot_caps(current); + + gr_handle_chroot_chdir(nd.dentry, nd.mnt); +#endif + error = 0; dput_and_out: path_release(&nd); @@ -484,6 +497,14 @@ goto out_putf; if (mode == (mode_t) -1) mode = inode->i_mode; + +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) { + err = -EPERM; + goto out_putf; + } +#endif + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; err = notify_change(dentry, &newattrs); @@ -516,6 +535,14 @@ if (mode == (mode_t) -1) mode = inode->i_mode; + +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) { + error = -EACCES; + goto dput_and_out; + } +#endif + newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; error = notify_change(nd.dentry, &newattrs); diff -urN linux-2.4.22/fs/proc/array.c linux-2.4.22-grsec/fs/proc/array.c --- linux-2.4.22/fs/proc/array.c 2003-10-09 18:46:57.000000000 +0200 +++ linux-2.4.22-grsec/fs/proc/array.c 2003-10-09 19:13:26.000000000 +0200 @@ -683,6 +683,16 @@ return retval; } +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR +int proc_pid_ipaddr(struct task_struct *task, char * buffer) +{ + int len; + + len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip)); + return len; +} +#endif + #ifdef CONFIG_SMP int proc_pid_cpu(struct task_struct *task, char * buffer) { diff -urN linux-2.4.22/fs/proc/base.c linux-2.4.22-grsec/fs/proc/base.c --- linux-2.4.22/fs/proc/base.c 2003-08-25 13:44:43.000000000 +0200 +++ linux-2.4.22-grsec/fs/proc/base.c 2003-10-09 19:13:26.000000000 +0200 @@ -25,6 +25,7 @@ #include #include #include +#include /* * For hysterical raisins we keep the same inumbers as in the old procfs. @@ -41,6 +42,9 @@ int proc_pid_status(struct task_struct*,char*); int proc_pid_statm(struct task_struct*,char*); int proc_pid_cpu(struct task_struct*,char*); +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR +int proc_pid_ipaddr(struct task_struct*,char*); +#endif static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { @@ -576,6 +580,9 @@ PROC_PID_STATM, PROC_PID_MAPS, PROC_PID_CPU, +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR + PROC_PID_IPADDR, +#endif PROC_PID_MOUNTS, PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */ }; @@ -591,6 +598,9 @@ #ifdef CONFIG_SMP E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUGO), #endif +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR + E(PROC_PID_IPADDR, "ipaddr", S_IFREG|S_IRUSR), +#endif E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUGO), E(PROC_PID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR), E(PROC_PID_CWD, "cwd", S_IFLNK|S_IRWXUGO), @@ -958,6 +968,12 @@ inode->u.proc_i.op.proc_read = proc_pid_cpu; break; #endif +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR + case PROC_PID_IPADDR: + inode->i_fop = &proc_info_file_operations; + inode->u.proc_i.op.proc_read = proc_pid_ipaddr; + break; +#endif case PROC_PID_MEM: inode->i_op = &proc_mem_inode_operations; inode->i_fop = &proc_mem_operations; @@ -1102,6 +1118,10 @@ int pid = p->pid; if (!pid) continue; +#ifdef CONFIG_GRKERNSEC + if(gr_pid_is_chrooted(p)) + continue; +#endif if (--index >= 0) continue; pids[nr_pids] = pid; diff -urN linux-2.4.22/grsecurity/Config.in linux-2.4.22-grsec/grsecurity/Config.in --- linux-2.4.22/grsecurity/Config.in 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/grsecurity/Config.in 2003-10-09 19:13:26.000000000 +0200 @@ -0,0 +1,39 @@ +bool 'Deny mounts' CONFIG_GRKERNSEC_CHROOT_MOUNT +bool 'Deny double-chroots' CONFIG_GRKERNSEC_CHROOT_DOUBLE +bool 'Deny pivot_root in chroot' CONFIG_GRKERNSEC_CHROOT_PIVOT +bool 'Enforce chdir("/") on all chroots' CONFIG_GRKERNSEC_CHROOT_CHDIR +bool 'Deny (f)chmod +s' CONFIG_GRKERNSEC_CHROOT_CHMOD +bool 'Deny fchdir out of chroot' CONFIG_GRKERNSEC_CHROOT_FCHDIR +bool 'Deny mknod' CONFIG_GRKERNSEC_CHROOT_MKNOD +bool 'Deny shmat() out of chroot' CONFIG_GRKERNSEC_CHROOT_SHMAT +bool 'Deny access to abstract AF_UNIX sockets out of chroot' CONFIG_GRKERNSEC_CHROOT_UNIX +bool 'Protect outside processes' CONFIG_GRKERNSEC_CHROOT_FINDTASK +bool 'Restrict priority changes' CONFIG_GRKERNSEC_CHROOT_NICE +bool 'Deny sysctl writes in chroot' CONFIG_GRKERNSEC_CHROOT_SYSCTL +bool 'Capability restrictions within chroot' CONFIG_GRKERNSEC_CHROOT_CAPS +bool 'Trusted path execution' CONFIG_GRKERNSEC_TPE +if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; then +bool ' Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL +int ' GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005 +fi +bool 'Socket restrictions' CONFIG_GRKERNSEC_SOCKET +if [ "$CONFIG_GRKERNSEC_SOCKET" != "n" ]; then +bool ' Deny any sockets to group' CONFIG_GRKERNSEC_SOCKET_ALL +if [ "$CONFIG_GRKERNSEC_SOCKET_ALL" != "n" ]; then +int ' GID to deny all sockets for:' CONFIG_GRKERNSEC_SOCKET_ALL_GID 1004 +fi +bool ' Deny client sockets to group' CONFIG_GRKERNSEC_SOCKET_CLIENT +if [ "$CONFIG_GRKERNSEC_SOCKET_CLIENT" != "n" ]; then +int ' GID to deny client sockets for:' CONFIG_GRKERNSEC_SOCKET_CLIENT_GID 1003 +fi +bool ' Deny server sockets to group' CONFIG_GRKERNSEC_SOCKET_SERVER +if [ "$CONFIG_GRKERNSEC_SOCKET_SERVER" != "n" ]; then +int ' GID to deny server sockets for:' CONFIG_GRKERNSEC_SOCKET_SERVER_GID 1002 +fi +fi +bool '/proc//ipaddr support' CONFIG_GRKERNSEC_PROC_IPADDR +int 'Seconds in between log messages (minimum)' CONFIG_GRKERNSEC_FLOODTIME 10 +int 'Number of messages in a burst (maximum)' CONFIG_GRKERNSEC_FLOODBURST 4 +if [ "$CONFIG_SYSCTL" != "n" ]; then +bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL +fi diff -urN linux-2.4.22/grsecurity/Makefile linux-2.4.22-grsec/grsecurity/Makefile --- linux-2.4.22/grsecurity/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/grsecurity/Makefile 2003-10-09 19:19:48.000000000 +0200 @@ -0,0 +1,13 @@ +# grsecurity's ACL system was originally written in 2001 by Michael Dalton +# during 2001, 2002, and 2003 it has been completely redesigned by +# Brad Spengler +# +# All code in this directory and various hooks inserted throughout the kernel +# are copyright Brad Spengler, and released under the GPL, unless otherwise +# noted (as in obsd_rand.c) + +O_TARGET := grsec.o + +obj-$(CONFIG_GRKERNSEC) = grsec_chroot.o grsec_sysctl.o grsec_init.o grsec_sock.o grsec_tpe.o + +include $(TOPDIR)/Rules.make diff -urN linux-2.4.22/grsecurity/grsec_chroot.c linux-2.4.22-grsec/grsecurity/grsec_chroot.c --- linux-2.4.22/grsecurity/grsec_chroot.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/grsecurity/grsec_chroot.c 2003-10-09 19:13:26.000000000 +0200 @@ -0,0 +1,402 @@ +#include +#include +#include +#include +#include +#include + +static __inline__ char * +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt, + char *buf, int buflen) +{ + char *res; + struct dentry *our_dentry; + struct vfsmount *our_mount; + struct vfsmount *rootmnt; + struct dentry *root; + + our_dentry = (struct dentry *) dentry; + our_mount = (struct vfsmount *) vfsmnt; + + read_lock(&child_reaper->fs->lock); + rootmnt = mntget(child_reaper->fs->rootmnt); + root = dget(child_reaper->fs->root); + read_unlock(&child_reaper->fs->lock); + + spin_lock(&dcache_lock); + res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen); + spin_unlock(&dcache_lock); + dput(root); + mntput(rootmnt); + return res; +} + +char * +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt) +{ + return d_real_path(dentry, mnt, gr_shared_page[0][smp_processor_id()], + PAGE_SIZE); +} + +char * +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt) +{ + return d_real_path(dentry, mnt, gr_shared_page[1][smp_processor_id()], + PAGE_SIZE); +} + +char * +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt) +{ + return d_real_path(dentry, mnt, gr_shared_page[2][smp_processor_id()], + PAGE_SIZE); +} + +char * +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt) +{ + return d_real_path(dentry, mnt, gr_shared_page[3][smp_processor_id()], + PAGE_SIZE); +} + +int +gr_handle_chroot_unix(const pid_t pid) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX + struct task_struct *p, **htable; + + if (unlikely(!grsec_enable_chroot_unix)) + return 1; + + if (likely(!proc_is_chrooted(current))) + return 1; + + read_lock(&tasklist_lock); + + htable = &pidhash[pid_hashfn(pid)]; + + for (p = *htable; p && p->pid != pid; p = p->pidhash_next) ; + + if (unlikely(p && !have_same_root(current, p))) { + read_unlock(&tasklist_lock); + gr_security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS); + return 0; + } + read_unlock(&tasklist_lock); +#endif + return 1; +} + +int +gr_handle_chroot_nice(void) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE + if (grsec_enable_chroot_nice && proc_is_chrooted(current)) { + gr_security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS); + return -EPERM; + } +#endif + return 0; +} + +int +gr_handle_chroot_setpriority(const struct task_struct *p, const int niceval) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE + if (grsec_enable_chroot_nice && (!have_same_root(p, current) + || (have_same_root(p, current) + && (niceval < task_nice(p)) + && proc_is_chrooted(current)))) { + gr_security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid, + DEFAULTSECARGS); + return -ESRCH; + } +#endif + return 0; +} + +int +gr_handle_chroot_capset(const struct task_struct *target) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS + if (grsec_enable_chroot_caps && proc_is_chrooted(current) && + !have_same_root(current, target)) { + gr_security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid, + DEFAULTSECARGS); + return 1; + } +#endif + return 0; +} + +int +gr_handle_chroot_rawio(const struct inode *inode) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS + if (grsec_enable_chroot_caps && proc_is_chrooted(current) && + inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO)) + return 1; +#endif + return 0; +} + +int +gr_pid_is_chrooted(const struct task_struct *p) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK + if (!grsec_enable_chroot_findtask || (current->pid <= 1)) + return 0; + + if (p && p->fs && p->fs->root && p->fs->root->d_inode && + child_reaper && child_reaper->fs && child_reaper->fs->root && + child_reaper->fs->root->d_inode && current && current->fs && + current->fs->root && current->fs->root->d_inode) { + if (proc_is_chrooted(current) && !have_same_root(current, p)) + return 1; + } +#endif + return 0; +} + +int +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR + if (!grsec_enable_chroot_fchdir) + return 1; + + if (!proc_is_chrooted(current)) + return 1; + else { + struct dentry *dentry = u_dentry; + struct vfsmount *mnt = u_mnt; + struct dentry *realroot; + struct vfsmount *realrootmnt; + struct dentry *currentroot; + struct vfsmount *currentmnt; + + read_lock(&child_reaper->fs->lock); + realrootmnt = mntget(child_reaper->fs->rootmnt); + realroot = dget(child_reaper->fs->root); + read_unlock(&child_reaper->fs->lock); + + read_lock(¤t->fs->lock); + currentmnt = mntget(current->fs->rootmnt); + currentroot = dget(current->fs->root); + read_unlock(¤t->fs->lock); + + spin_lock(&dcache_lock); + for (;;) { + if (unlikely + ((dentry == realroot && mnt == realrootmnt) + || (dentry == currentroot && mnt == currentmnt))) + break; + if (unlikely + (dentry == mnt->mnt_root || IS_ROOT(dentry))) { + if (mnt->mnt_parent == mnt) + break; + dentry = mnt->mnt_mountpoint; + mnt = mnt->mnt_parent; + continue; + } + dentry = dentry->d_parent; + } + spin_unlock(&dcache_lock); + + dput(currentroot); + mntput(currentmnt); + + if (dentry == realroot && mnt == realrootmnt) { + /* ok, they're definitely trying to fchdir outside of the + chroot. */ + dput(realroot); + mntput(realrootmnt); + gr_security_alert(GR_CHROOT_FCHDIR_MSG, + gr_to_filename(u_dentry, u_mnt), + DEFAULTSECARGS); + return 0; + } else { + dput(realroot); + mntput(realrootmnt); + return 1; + } + } +#endif + return 1; +} + +int +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid, + const time_t shm_createtime) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT + struct task_struct *p, **htable; + + if (unlikely(!grsec_enable_chroot_shmat)) + return 1; + + if (likely(!proc_is_chrooted(current))) + return 1; + + read_lock(&tasklist_lock); + + htable = &pidhash[pid_hashfn(shm_cprid)]; + + for (p = *htable; p && p->pid != shm_cprid; p = p->pidhash_next) ; + + if (unlikely(p && !have_same_root(current, p) && + (p->start_time < shm_createtime))) { + read_unlock(&tasklist_lock); + gr_security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS); + return 0; + } + + if (unlikely(!p)) { + htable = &pidhash[pid_hashfn(shm_lapid)]; + for (p = *htable; p && p->pid != shm_lapid; + p = p->pidhash_next) ; + + if (unlikely(p && !have_same_root(current, p))) { + read_unlock(&tasklist_lock); + gr_security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS); + return 0; + } + } + + read_unlock(&tasklist_lock); +#endif + return 1; +} + +void +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG + if (grsec_enable_chroot_execlog && proc_is_chrooted(current)) + security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt), + DEFAULTSECARGS); +#endif + return; +} + +int +gr_handle_chroot_mknod(const struct dentry *dentry, + const struct vfsmount *mnt, const int mode) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD + if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && + proc_is_chrooted(current)) { + gr_security_alert(GR_MKNOD_CHROOT_MSG, + gr_to_filename(dentry, mnt), DEFAULTSECARGS); + return -EPERM; + } +#endif + return 0; +} + +int +gr_handle_chroot_mount(const struct dentry *dentry, + const struct vfsmount *mnt, const char *dev_name) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT + if (grsec_enable_chroot_mount && proc_is_chrooted(current)) { + gr_security_alert(GR_MOUNT_CHROOT_MSG, dev_name, + gr_to_filename(dentry, mnt), DEFAULTSECARGS); + return -EPERM; + } +#endif + return 0; +} + +int +gr_handle_chroot_pivot(void) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT + if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) { + gr_security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS); + return -EPERM; + } +#endif + return 0; +} + +int +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE + if (grsec_enable_chroot_double && proc_is_chrooted(current)) { + gr_security_alert(GR_CHROOT_CHROOT_MSG, + gr_to_filename(dentry, mnt), DEFAULTSECARGS); + return -EPERM; + } +#endif + return 0; +} + +void +gr_handle_chroot_caps(struct task_struct *task) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS + if (grsec_enable_chroot_caps && proc_is_chrooted(task)) { + task->cap_permitted = + cap_drop(task->cap_permitted, GR_CHROOT_CAPS); + task->cap_inheritable = + cap_drop(task->cap_inheritable, GR_CHROOT_CAPS); + task->cap_effective = + cap_drop(task->cap_effective, GR_CHROOT_CAPS); + } +#endif + return; +} + +int +gr_handle_chroot_sysctl(const int op) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL + if (grsec_enable_chroot_sysctl && proc_is_chrooted(current) + && (op & 002)) + return -EACCES; +#endif + return 0; +} + +void +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR + if (grsec_enable_chroot_chdir) + set_fs_pwd(current->fs, mnt, dentry); +#endif + return; +} + +int +gr_handle_chroot_chmod(const struct dentry *dentry, + const struct vfsmount *mnt, const int mode) +{ +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD + if (grsec_enable_chroot_chmod && + ((mode & S_ISUID) || (mode & S_ISGID)) && + proc_is_chrooted(current)) { + gr_security_alert(GR_CHMOD_CHROOT_MSG, + gr_to_filename(dentry, mnt), DEFAULTSECARGS); + return -EPERM; + } +#endif + return 0; +} + +__inline__ void +gr_copy_label(struct task_struct *tsk) +{ + tsk->used_accept = 0; + tsk->used_connect = 0; + tsk->curr_ip = current->curr_ip; + if (current->exec_file) + get_file(current->exec_file); + tsk->exec_file = current->exec_file; + if (unlikely(current->used_accept)) + current->curr_ip = 0; + + return; +} diff -urN linux-2.4.22/grsecurity/grsec_init.c linux-2.4.22-grsec/grsecurity/grsec_init.c --- linux-2.4.22/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/grsecurity/grsec_init.c 2003-10-09 19:16:48.000000000 +0200 @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include + +int grsec_enable_chroot_findtask; +int grsec_enable_chroot_mount; +int grsec_enable_chroot_shmat; +int grsec_enable_chroot_fchdir; +int grsec_enable_chroot_double; +int grsec_enable_chroot_pivot; +int grsec_enable_chroot_chdir; +int grsec_enable_chroot_chmod; +int grsec_enable_chroot_mknod; +int grsec_enable_chroot_nice; +int grsec_enable_chroot_execlog; +int grsec_enable_chroot_caps; +int grsec_enable_chroot_sysctl; +int grsec_enable_chroot_unix; +int grsec_enable_tpe; +int grsec_tpe_gid; +int grsec_enable_tpe_all; +int grsec_enable_socket_all; +int grsec_socket_all_gid; +int grsec_enable_socket_client; +int grsec_socket_client_gid; +int grsec_enable_socket_server; +int grsec_socket_server_gid; +int grsec_lock; + +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED; +unsigned long grsec_alert_wtime = 0; +unsigned long grsec_alert_fyet = 0; + +spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED; +unsigned long grsec_alertgood_wtime = 0; +unsigned long grsec_alertgood_fyet = 0; + +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED; + +char *gr_shared_page[4][NR_CPUS]; + +void +grsecurity_init(void) +{ + int i, j; + /* create the per-cpu shared pages */ + + for (j = 0; j < 4; j++) { + for (i = 0; i < NR_CPUS; i++) { + gr_shared_page[j][i] = (char *) get_zeroed_page(GFP_KERNEL); + if (!gr_shared_page[j][i]) { + panic("Unable to allocate grsecurity shared page"); + return; + } + } + } + +#ifndef CONFIG_GRKERNSEC_SYSCTL + grsec_lock = 1; +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK + grsec_enable_chroot_findtask = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX + grsec_enable_chroot_unix = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT + grsec_enable_chroot_mount = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR + grsec_enable_chroot_fchdir = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT + grsec_enable_chroot_shmat = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE + grsec_enable_chroot_double = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT + grsec_enable_chroot_pivot = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR + grsec_enable_chroot_chdir = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD + grsec_enable_chroot_chmod = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD + grsec_enable_chroot_mknod = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE + grsec_enable_chroot_nice = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG + grsec_enable_chroot_execlog = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS + grsec_enable_chroot_caps = 1; +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL + grsec_enable_chroot_sysctl = 1; +#endif +#ifdef CONFIG_GRKERNSEC_TPE + grsec_enable_tpe = 1; + grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID; +#ifdef CONFIG_GRKERNSEC_TPE_ALL + grsec_enable_tpe_all = 1; +#endif +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL + grsec_enable_socket_all = 1; + grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID; +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT + grsec_enable_socket_client = 1; + grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID; +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER + grsec_enable_socket_server = 1; + grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID; +#endif +#endif + + return; +} diff -urN linux-2.4.22/grsecurity/grsec_sock.c linux-2.4.22/grsecurity/grsec_sock.c --- linux-2.4.22/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.4.22/grsecurity/grsec_sock.c 2003-09-02 19:29:42.000000000 -0400 @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include + +void +gr_attach_curr_ip(const struct sock *sk) +{ +#ifdef CONFIG_GRKERNSEC + struct task_struct *p; + unsigned int i; + struct inode *inode; + struct file *filp; + struct socket *connect_sock; + + if (unlikely(sk->protocol != IPPROTO_TCP)) + return; + + read_lock(&tasklist_lock); + for_each_task(p) { + if (!p->used_connect) + continue; + task_lock(p); + if (unlikely(!p->files)) { + task_unlock(p); + continue; + } + read_lock(&p->files->file_lock); + for (i = 0; i < p->files->max_fds; i++) { + filp = fcheck_files(p->files, i); + if (likely(!filp)) + continue; + inode = filp->f_dentry->d_inode; + if (likely(!inode || !inode->i_sock)) + continue; + connect_sock = &inode->u.socket_i; + if (unlikely(!connect_sock || + connect_sock->sk->protocol != IPPROTO_TCP)) + continue; + if (unlikely(sk->rcv_saddr == connect_sock->sk->daddr && + sk->daddr == connect_sock->sk->rcv_saddr && + ntohs(sk->sport) == + ntohs(connect_sock->sk->dport) + && ntohs(sk->dport) == + ntohs(connect_sock->sk->sport))) { + current->curr_ip = p->curr_ip; + current->used_accept = 1; + read_unlock(&p->files->file_lock); + task_unlock(p); + read_unlock(&tasklist_lock); + return; + } + } + read_unlock(&p->files->file_lock); + task_unlock(p); + } + read_unlock(&tasklist_lock); + + current->curr_ip = sk->daddr; + current->used_accept = 1; +#endif + return; +} + +int +gr_handle_sock_all(const int family, const int type, const int protocol) +{ +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL + if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) && + (family != AF_UNIX) && (family != AF_LOCAL)) { + gr_security_alert(GR_SOCK_MSG, family, type, protocol, + DEFAULTSECARGS); + return -EACCES; + } +#endif + return 0; +} + +int +gr_handle_sock_server(const struct sockaddr *sck) +{ +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER + if (grsec_enable_socket_server && + in_group_p(grsec_socket_server_gid) && + sck && (sck->sa_family != AF_UNIX) && + (sck->sa_family != AF_LOCAL)) { + gr_security_alert(GR_BIND_MSG, DEFAULTSECARGS); + return -EACCES; + } +#endif + return 0; +} + +int +gr_handle_sock_client(const struct sockaddr *sck) +{ +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT + if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) && + sck && (sck->sa_family != AF_UNIX) && + (sck->sa_family != AF_LOCAL)) { + gr_security_alert(GR_CONNECT_MSG, DEFAULTSECARGS); + return -EACCES; + } +#endif + return 0; +} diff -urN linux-2.4.22/grsecurity/grsec_sysctl.c linux-2.4.22-grsec/grsecurity/grsec_sysctl.c --- linux-2.4.22/grsecurity/grsec_sysctl.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/grsecurity/grsec_sysctl.c 2003-10-09 19:13:26.000000000 +0200 @@ -0,0 +1,16 @@ +#include +#include +#include +#include + +int +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op) +{ +#ifdef CONFIG_GRKERNSEC_SYSCTL + if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) { + gr_security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS); + return -EACCES; + } +#endif + return 0; +} diff -urN linux-2.4.22/grsecurity/grsec_tpe.c linux-2.4.22/grsecurity/grsec_tpe.c --- linux-2.4.22/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.4.22/grsecurity/grsec_tpe.c 2003-09-02 19:29:42.000000000 -0400 @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int +gr_tpe_allow(const struct file *file) +{ +#ifdef CONFIG_GRKERNSEC + struct inode *inode = file->f_dentry->d_parent->d_inode; + + if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid))) && + (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) || + (inode->i_mode & S_IWOTH))))) { + gr_security_alert(GR_EXEC_TPE_MSG, + gr_to_filename(file->f_dentry, file->f_vfsmnt), + DEFAULTSECARGS); + return 0; + } +#ifdef CONFIG_GRKERNSEC_TPE_ALL + if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all && + ((inode->i_uid && (inode->i_uid != current->uid)) || + (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) { + gr_security_alert(GR_EXEC_TPE_MSG, + gr_to_filename(file->f_dentry, file->f_vfsmnt), + DEFAULTSECARGS); + return 0; + } +#endif +#endif + return 1; +} diff -urN linux-2.4.22/include/linux/grinternal.h linux-2.4.22-grsec/include/linux/grinternal.h --- linux-2.4.22/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/include/linux/grinternal.h 2003-10-09 19:13:26.000000000 +0200 @@ -0,0 +1,130 @@ +#ifndef __GRINTERNAL_H +#define __GRINTERNAL_H + +#ifdef CONFIG_GRKERNSEC + +#include + +extern char *gr_shared_page[4][NR_CPUS]; + +extern char *gr_to_filename(const struct dentry *dentry, + const struct vfsmount *mnt); +extern char *gr_to_filename1(const struct dentry *dentry, + const struct vfsmount *mnt); +extern char *gr_to_filename2(const struct dentry *dentry, + const struct vfsmount *mnt); +extern char *gr_to_filename3(const struct dentry *dentry, + const struct vfsmount *mnt); + +extern int grsec_enable_chroot_shmat; +extern int grsec_enable_chroot_findtask; +extern int grsec_enable_chroot_mount; +extern int grsec_enable_chroot_double; +extern int grsec_enable_chroot_pivot; +extern int grsec_enable_chroot_chdir; +extern int grsec_enable_chroot_chmod; +extern int grsec_enable_chroot_mknod; +extern int grsec_enable_chroot_fchdir; +extern int grsec_enable_chroot_nice; +extern int grsec_enable_chroot_execlog; +extern int grsec_enable_chroot_caps; +extern int grsec_enable_chroot_sysctl; +extern int grsec_enable_chroot_unix; +extern int grsec_enable_tpe; +extern int grsec_tpe_gid; +extern int grsec_enable_tpe_all; +extern int grsec_enable_socket_all; +extern int grsec_socket_all_gid; +extern int grsec_enable_socket_client; +extern int grsec_socket_client_gid; +extern int grsec_enable_socket_server; +extern int grsec_socket_server_gid; +extern int grsec_lock; + +extern struct task_struct *child_reaper; + +extern spinlock_t grsec_alert_lock; +extern unsigned long grsec_alert_wtime; +extern unsigned long grsec_alert_fyet; + +extern spinlock_t grsec_alertgood_lock; +extern unsigned long grsec_alertgood_wtime; +extern unsigned long grsec_alertgood_fyet; + +extern spinlock_t grsec_audit_lock; + +#define gr_task_fullpath(tsk) (tsk->exec_file ? \ + gr_to_filename2(tsk->exec_file->f_dentry, \ + tsk->exec_file->f_vfsmnt) : "/") + +#define gr_parent_task_fullpath(tsk) (tsk->p_pptr->exec_file ? \ + gr_to_filename3(tsk->p_pptr->exec_file->f_dentry, \ + tsk->p_pptr->exec_file->f_vfsmnt) : "/") + +#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && \ + ((tsk_a->fs->root->d_inode->i_dev != \ + child_reaper->fs->root->d_inode->i_dev) || \ + (tsk_a->fs->root->d_inode->i_ino != \ + child_reaper->fs->root->d_inode->i_ino))) + +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_dev == \ + tsk_b->fs->root->d_inode->i_dev) && \ + (tsk_a->fs->root->d_inode->i_ino == \ + tsk_b->fs->root->d_inode->i_ino)) + +#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \ + current->pid, current->uid, \ + current->euid, current->gid, current->egid, \ + gr_parent_task_fullpath(current), \ + current->p_pptr->comm, current->p_pptr->pid, \ + current->p_pptr->uid, current->p_pptr->euid, \ + current->p_pptr->gid, current->p_pptr->egid + +#define GR_CHROOT_CAPS ( \ + CAP_TO_MASK(CAP_FOWNER) | \ + CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \ + CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \ + CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \ + CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \ + CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \ + CAP_TO_MASK(CAP_IPC_OWNER)) + +#define gr_security_alert(normal_msg,args...) \ +({ \ + spin_lock(&grsec_alert_lock); \ + \ + if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \ + grsec_alert_wtime = jiffies; grsec_alert_fyet = 0; \ + if (current->curr_ip) \ + printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \ + else \ + printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \ + } else if((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \ + grsec_alert_fyet++; \ + if (current->curr_ip) \ + printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \ + else \ + printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \ + } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \ + grsec_alert_wtime = jiffies; grsec_alert_fyet++; \ + printk(KERN_ALERT "grsec: more alerts, logging disabled for " \ + "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \ + } \ + \ + spin_unlock(&grsec_alert_lock); \ +}) + +#define security_audit(normal_msg,args...) \ +({ \ + spin_lock(&grsec_audit_lock); \ + if (current->curr_ip) \ + printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \ + NIPQUAD(current->curr_ip) , ## args); \ + else \ + printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \ + spin_unlock(&grsec_audit_lock); \ +}) + +#endif + +#endif diff -urN linux-2.4.22/include/linux/grmsg.h linux-2.4.22-grsec/include/linux/grmsg.h --- linux-2.4.22/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/include/linux/grmsg.h 2003-10-09 19:13:26.000000000 +0200 @@ -0,0 +1,18 @@ +#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d, parent %.256s[%.16s:%d] uid/euid:%d/%d gid/egid:%d/%d" +#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG +#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG +#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG +#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG +#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG +#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG +#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG +#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG +#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG +#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG +#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG +#define GR_SOCK_MSG "attempted socket(%d,%d,%d) by " DEFAULTSECMSG +#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG +#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG diff -urN linux-2.4.22/include/linux/grsecurity.h linux-2.4.22-grsec/include/linux/grsecurity.h --- linux-2.4.22/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/include/linux/grsecurity.h 2003-10-09 19:13:26.000000000 +0200 @@ -0,0 +1,32 @@ +#ifndef GR_SECURITY_H +#define GR_SECURITY_H + +extern int gr_pid_is_chrooted(const struct task_struct *p); +extern int gr_handle_chroot_nice(void); +extern int gr_handle_chroot_sysctl(const int op); +extern int gr_handle_chroot_capset(const struct task_struct *target); +extern int gr_handle_chroot_setpriority(const struct task_struct *p, + const int niceval); +extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt); +extern int gr_handle_chroot_chroot(const struct dentry *dentry, + const struct vfsmount *mnt); +extern void gr_handle_chroot_caps(struct task_struct *task); +extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt); +extern int gr_handle_chroot_chmod(const struct dentry *dentry, + const struct vfsmount *mnt, const int mode); +extern int gr_handle_chroot_mknod(const struct dentry *dentry, + const struct vfsmount *mnt, const int mode); +extern int gr_handle_chroot_mount(const struct dentry *dentry, + const struct vfsmount *mnt, + const char *dev_name); +extern int gr_handle_chroot_pivot(void); +extern int gr_handle_chroot_unix(const pid_t pid); + +extern void gr_log_chroot_exec(const struct dentry *dentry, + const struct vfsmount *mnt); + +extern void gr_copy_label(struct task_struct *tsk); + +extern int gr_tpe_allow(const struct file *file); + +#endif diff -urN linux-2.4.22/include/linux/sched.h linux-2.4.22-grsec/include/linux/sched.h --- linux-2.4.22/include/linux/sched.h 2003-10-09 18:47:38.000000000 +0200 +++ linux-2.4.22-grsec/include/linux/sched.h 2003-10-09 19:13:26.000000000 +0200 @@ -28,6 +28,8 @@ #include #include +extern int gr_pid_is_chrooted(const struct task_struct *p); + struct exec_domain; /* @@ -415,6 +432,13 @@ /* journalling filesystem info */ void *journal_info; + +#ifdef CONFIG_GRKERNSEC + struct file *exec_file; + u32 curr_ip; + u8 used_accept:1; + u8 used_connect:1; +#endif }; /* @@ -556,6 +595,10 @@ for(p = *htable; p && p->pid != pid; p = p->pidhash_next) ; +#ifdef CONFIG_GRKERNSEC + if(gr_pid_is_chrooted(p)) p = NULL; +#endif + return p; } @@ -583,6 +585,10 @@ for(p = *htable; p && p->pid != pid; p = p->pidhash_next) ; +#ifdef CONFIG_GRKERNSEC + if(gr_pid_is_chrooted(p)) p = NULL; +#endif + return p; } diff -urN linux-2.4.22/include/linux/sysctl.h linux-2.4.22-grsec/include/linux/sysctl.h --- linux-2.4.22/include/linux/sysctl.h 2003-10-09 18:47:24.000000000 +0200 +++ linux-2.4.22-grsec/include/linux/sysctl.h 2003-10-09 19:13:26.000000000 +0200 @@ -127,6 +127,7 @@ KERN_CORE_PATTERN=56, /* string: pattern for core-files */ KERN_PPC_L3CR=57, /* l3cr register on PPC */ KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */ + KERN_GRSECURITY=68, /* grsecurity */ }; diff -urN linux-2.4.22/init/main.c linux-2.4.22-grsec/init/main.c --- linux-2.4.22/init/main.c 2003-10-09 18:47:32.000000000 +0200 +++ linux-2.4.22-grsec/init/main.c 2003-10-09 19:13:26.000000000 +0200 @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -112,6 +113,8 @@ extern void ipc_init(void); #endif +extern void grsecurity_init(void); + /* * Boot command-line arguments */ @@ -563,6 +566,9 @@ do_basic_setup(); prepare_namespace(); +#ifdef CONFIG_GRKERNSEC + grsecurity_init(); +#endif /* * Ok, we have completed the initial bootup, and diff -urN linux-2.4.22/ipc/shm.c linux-2.4.22-grsec/ipc/shm.c --- linux-2.4.22/ipc/shm.c 2002-08-03 02:39:46.000000000 +0200 +++ linux-2.4.22-grsec/ipc/shm.c 2003-10-09 19:13:26.000000000 +0200 @@ -23,6 +23,7 @@ #include #include #include +#include #include "util.h" @@ -38,8 +39,18 @@ time_t shm_ctim; pid_t shm_cprid; pid_t shm_lprid; + +#ifdef CONFIG_GRKERNSEC + time_t shm_createtime; + pid_t shm_lapid; +#endif }; +#ifdef CONFIG_GRKERNSEC +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid, + const time_t shm_createtime); +#endif + #define shm_flags shm_perm.mode static struct file_operations shm_file_operations; @@ -209,6 +220,9 @@ shp->shm_lprid = 0; shp->shm_atim = shp->shm_dtim = 0; shp->shm_ctim = CURRENT_TIME; +#ifdef CONFIG_GRKERNSEC + shp->shm_createtime = CURRENT_TIME; +#endif shp->shm_segsz = size; shp->shm_nattch = 0; shp->id = shm_buildid(id,shp->shm_perm.seq); @@ -622,9 +636,22 @@ shm_unlock(shmid); return -EACCES; } + +#ifdef CONFIG_GRKERNSEC + if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) { + shm_unlock(shmid); + return -EACCES; + } +#endif + file = shp->shm_file; size = file->f_dentry->d_inode->i_size; shp->shm_nattch++; + +#ifdef CONFIG_GRKERNSEC + shp->shm_lapid = current->pid; +#endif + shm_unlock(shmid); down_write(¤t->mm->mmap_sem); diff -urN linux-2.4.22/kernel/capability.c linux-2.4.22-grsec/kernel/capability.c --- linux-2.4.22/kernel/capability.c 2003-10-09 18:46:57.000000000 +0200 +++ linux-2.4.22-grsec/kernel/capability.c 2003-10-09 19:13:26.000000000 +0200 @@ -7,6 +7,7 @@ #include #include +#include unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ @@ -170,6 +171,12 @@ target = current; } +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_capset(target)) { + error = -ESRCH; + goto out; + } +#endif /* verify restrictions on target's new Inheritable set */ if (!cap_issubset(inheritable, diff -urN linux-2.4.22/kernel/exit.c linux-2.4.22/kernel/exit.c --- linux-2.4.22/kernel/exit.c 2003-09-01 22:19:01.000000000 -0400 +++ linux-2.4.22/kernel/exit.c 2003-09-02 19:29:42.000000000 -0400 @@ -16,6 +16,8 @@ #ifdef CONFIG_BSD_PROCESS_ACCT #include #endif +#include +#include #include #include @@ -165,6 +165,13 @@ write_lock_irq(&tasklist_lock); +#ifdef CONFIG_GRKERNSEC + if (current->exec_file) { + fput(current->exec_file); + current->exec_file = NULL; + } +#endif + /* Reparent to init */ REMOVE_LINKS(current); current->p_pptr = child_reaper; diff -urN linux-2.4.22/kernel/fork.c linux-2.4.22/kernel/fork.c --- linux-2.4.22/kernel/fork.c 2003-09-01 22:19:01.000000000 -0400 +++ linux-2.4.22/kernel/fork.c 2003-09-02 19:29:42.000000000 -0400 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -751,6 +759,9 @@ retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); if (retval) goto bad_fork_cleanup_namespace; +#ifdef CONFIG_GRKERNSEC + gr_copy_label(p); +#endif p->semundo = NULL; /* Our parent execution domain becomes current domain diff -urN linux-2.4.22/kernel/ksyms.c linux-2.4.22-grsec/kernel/ksyms.c --- linux-2.4.22/kernel/ksyms.c 2003-10-09 18:47:35.000000000 +0200 +++ linux-2.4.22-grsec/kernel/ksyms.c 2003-10-09 19:13:26.000000000 +0200 @@ -50,6 +50,7 @@ #include #include #include +#include #include #if defined(CONFIG_PROC_FS) @@ -621,3 +622,8 @@ /* To match ksyms with System.map */ extern const char _end[]; EXPORT_SYMBOL(_end); + +/* grsecurity */ +#ifdef CONFIG_GRKERNSEC +EXPORT_SYMBOL(gr_pid_is_chrooted); +#endif diff -urN linux-2.4.22/kernel/sched.c linux-2.4.22-grsec/kernel/sched.c --- linux-2.4.22/kernel/sched.c 2003-10-09 18:47:25.000000000 +0200 +++ linux-2.4.22-grsec/kernel/sched.c 2003-10-09 19:13:26.000000000 +0200 @@ -20,11 +20,13 @@ #include #include #include +#include #include #include #include #include #include +#include /* * Convert user-nice values [ -20 ... 0 ... 19 ] @@ -1192,6 +1194,11 @@ return -EPERM; if (increment < -40) increment = -40; + +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_nice()) + return -EPERM; +#endif } if (increment > 40) increment = 40; diff -urN linux-2.4.22/kernel/sys.c linux-2.4.22-grsec/kernel/sys.c --- linux-2.4.22/kernel/sys.c 2003-10-09 18:46:57.000000000 +0200 +++ linux-2.4.22-grsec/kernel/sys.c 2003-10-09 19:13:26.000000000 +0200 @@ -4,6 +4,7 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -239,6 +241,14 @@ } if (error == -ESRCH) error = 0; + +#ifdef CONFIG_GRKERNSEC + if (gr_handle_chroot_setpriority(p, niceval)) { + read_unlock(&tasklist_lock); + return -ESRCH; + } +#endif + if (niceval < task_nice(p) && !capable(CAP_SYS_NICE)) error = -EACCES; else diff -urN linux-2.4.22/kernel/sysctl.c linux-2.4.22-grsec/kernel/sysctl.c --- linux-2.4.22/kernel/sysctl.c 2003-10-09 18:47:38.000000000 +0200 +++ linux-2.4.22-grsec/kernel/sysctl.c 2003-10-09 19:13:26.000000000 +0200 @@ -38,6 +38,11 @@ #endif #if defined(CONFIG_SYSCTL) +#include +#include + +extern int gr_handle_sysctl_mod(const char *dirname, const char *name, const int op); +extern int gr_handle_chroot_sysctl(const int op); /* External variables not in a header file. */ extern int panic_timeout; @@ -126,6 +135,8 @@ static ctl_table dev_table[]; extern ctl_table random_table[]; +static ctl_table grsecurity_table[]; + /* /proc declarations: */ #ifdef CONFIG_PROC_FS @@ -272,8 +283,112 @@ {KERN_EXCEPTION_TRACE,"exception-trace", &exception_trace,sizeof(int),0644,NULL,&proc_dointvec}, #endif +#ifdef CONFIG_GRKERNSEC_SYSCTL + {KERN_GRSECURITY, "grsecurity", NULL, 0, 0500, grsecurity_table}, +#endif + {0} +}; + +#ifdef CONFIG_GRKERNSEC_SYSCTL +enum {GS_CHROOT_SHMAT=1, GS_CHROOT_UNIX, GS_CHROOT_MNT, +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM, +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS, +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, +GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT, +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_LOCK}; + +static ctl_table grsecurity_table[] = { +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT + {GS_CHROOT_SHMAT, "chroot_deny_shmat", &grsec_enable_chroot_shmat, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX + {GS_CHROOT_UNIX, "chroot_deny_unix", &grsec_enable_chroot_unix, sizeof(int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT + {GS_CHROOT_MNT, "chroot_deny_mount", &grsec_enable_chroot_mount, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR + {GS_CHROOT_FCHDIR, "chroot_deny_fchdir", &grsec_enable_chroot_fchdir, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE + {GS_CHROOT_DBL, "chroot_deny_chroot", &grsec_enable_chroot_double, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT + {GS_CHROOT_PVT, "chroot_deny_pivot", &grsec_enable_chroot_pivot, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR + {GS_CHROOT_CD, "chroot_enforce_chdir", &grsec_enable_chroot_chdir, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD + {GS_CHROOT_CM, "chroot_deny_chmod", &grsec_enable_chroot_chmod, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD + {GS_CHROOT_MK, "chroot_deny_mknod", &grsec_enable_chroot_mknod, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE + {GS_CHROOT_NI, "chroot_restrict_nice", &grsec_enable_chroot_nice, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG + {GS_CHROOT_EXECLOG, "chroot_execlog", + &grsec_enable_chroot_execlog, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS + {GS_CHROOT_CAPS, "chroot_caps", &grsec_enable_chroot_caps, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL + {GS_CHROOT_SYSCTL, "chroot_deny_sysctl", &grsec_enable_chroot_sysctl, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_TPE + {GS_TPE, "tpe", &grsec_enable_tpe, sizeof (int), + 0600, NULL, &proc_dointvec}, + {GS_TPE_GID, "tpe_gid", &grsec_tpe_gid, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_TPE_ALL + {GS_TPE_ALL, "tpe_restrict_all", &grsec_enable_tpe_all, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL + {GS_SOCKET_ALL, "socket_all", &grsec_enable_socket_all, sizeof (int), + 0600, NULL, &proc_dointvec}, + {GS_SOCKET_ALL_GID, "socket_all_gid", + &grsec_socket_all_gid, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT + {GS_SOCKET_CLIENT, "socket_client", + &grsec_enable_socket_client, sizeof (int), + 0600, NULL, &proc_dointvec}, + {GS_SOCKET_CLIENT_GID, "socket_client_gid", + &grsec_socket_client_gid, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER + {GS_SOCKET_SERVER, "socket_server", + &grsec_enable_socket_server, sizeof (int), + 0600, NULL, &proc_dointvec}, + {GS_SOCKET_SERVER_GID, "socket_server_gid", + &grsec_socket_server_gid, sizeof (int), + 0600, NULL, &proc_dointvec}, +#endif + {GS_LOCK, "grsec_lock", &grsec_lock, sizeof (int), 0600, NULL, + &proc_dointvec}, {0} }; +#endif static ctl_table vm_table[] = { {VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0644, NULL, @@ -413,6 +607,13 @@ static inline int ctl_perm(ctl_table *table, int op) { +#ifdef CONFIG_GRKERNSEC + if (gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op)) + return -EACCES; + if (gr_handle_chroot_sysctl(op)) + return -EACCES; +#endif + return test_perm(table->mode, op); } diff -urN linux-2.4.22/mm/mmap.c linux-2.4.22/mm/mmap.c --- linux-2.4.22/mm/mmap.c 2003-09-01 22:19:02.000000000 -0400 +++ linux-2.4.22/mm/mmap.c 2003-09-02 19:29:42.000000000 -0400 @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include @@ -480,6 +532,11 @@ } } +#ifdef CONFIG_GRKERNSEC + if (!gr_tpe_allow(file)) + return -EACCES; +#endif + /* Clear old maps */ munmap_back: vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); diff -urN linux-2.4.22/mm/mprotect.c linux-2.4.22/mm/mprotect.c --- linux-2.4.22/mm/mprotect.c 2003-09-01 22:19:02.000000000 -0400 +++ linux-2.4.22/mm/mprotect.c 2003-09-02 19:29:42.000000000 -0400 @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -288,6 +393,13 @@ if (!vma || vma->vm_start > start) goto out; +#ifdef CONFIG_GRKERNSEC + if (!gr_tpe_allow(vma->vm_file)) { + error = -EACCES; + goto out; + } +#endif + for (nstart = start ; ; ) { unsigned int newflags; int last = 0; diff -urN linux-2.4.22/net/ipv4/netfilter/Config.in linux-2.4.22-grsec/net/ipv4/netfilter/Config.in --- linux-2.4.22/net/ipv4/netfilter/Config.in 2003-10-09 18:47:22.000000000 +0200 +++ linux-2.4.22-grsec/net/ipv4/netfilter/Config.in 2003-10-09 19:13:26.000000000 +0200 @@ -75,6 +75,7 @@ dep_tristate ' address type match support' CONFIG_IP_NF_MATCH_ADDRTYPE $CONFIG_IP_NF_IPTABLES dep_tristate ' tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $CONFIG_IP_NF_IPTABLES dep_tristate ' realm match support' CONFIG_IP_NF_MATCH_REALM $CONFIG_IP_NF_IPTABLES + dep_tristate ' stealth match support' CONFIG_IP_NF_MATCH_STEALTH $CONFIG_IP_NF_IPTABLES if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then dep_tristate ' Helper match support' CONFIG_IP_NF_MATCH_HELPER $CONFIG_IP_NF_IPTABLES fi diff -urN linux-2.4.22/net/ipv4/netfilter/Makefile linux-2.4.22-grsec/net/ipv4/netfilter/Makefile --- linux-2.4.22/net/ipv4/netfilter/Makefile 2003-10-09 18:47:21.000000000 +0200 +++ linux-2.4.22-grsec/net/ipv4/netfilter/Makefile 2003-10-09 19:13:26.000000000 +0200 @@ -175,6 +175,7 @@ obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o diff -urN linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c linux-2.4.22-grsec/net/ipv4/netfilter/ipt_stealth.c --- linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.22-grsec/net/ipv4/netfilter/ipt_stealth.c 2003-10-09 19:13:26.000000000 +0200 @@ -0,0 +1,109 @@ +/* Kernel module to add stealth support. + * + * Copyright (C) 2002 Brad Spengler + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +MODULE_LICENSE("GPL"); + +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + const void *hdr, + u_int16_t datalen, + int *hotdrop) +{ + struct iphdr *ip = skb->nh.iph; + struct tcphdr *th = (struct tcphdr *) hdr; + struct udphdr *uh = (struct udphdr *) hdr; + struct sock *sk = NULL; + + if (!ip || !hdr || offset) return 0; + + switch(ip->protocol) { + case IPPROTO_TCP: + if (datalen < sizeof(struct tcphdr)) { + *hotdrop = 1; + return 0; + } + if (!(th->syn && !th->ack)) return 0; + sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th->dest), ((struct rtable*)skb->dst)->rt_iif); + break; + case IPPROTO_UDP: + if (datalen < sizeof(struct udphdr)) { + *hotdrop = 1; + return 0; + } + sk = udp_v4_lookup(ip->saddr, uh->source, ip->daddr, uh->dest, skb->dev->ifindex); + break; + default: + return 0; + } + + if(!sk) // port is being listened on, match this + return 1; + else { + sock_put(sk); + return 0; + } +} + +/* Called when user tries to insert an entry of this type. */ +static int +checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (matchsize != IPT_ALIGN(0)) + return 0; + + if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) || + ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO))) + && (hook_mask & (1 << NF_IP_LOCAL_IN))) + return 1; + + printk("stealth: Only works on TCP and UDP for the INPUT chain.\n"); + + return 0; +} + + +static struct ipt_match stealth_match += { { NULL, NULL }, "stealth", &match, &checkentry, NULL, THIS_MODULE }; + +static int __init init(void) +{ + return ipt_register_match(&stealth_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&stealth_match); +} + +module_init(init); +module_exit(fini); diff -urN linux-2.4.22/net/netsyms.c linux-2.4.22-grsec/net/netsyms.c --- linux-2.4.22/net/netsyms.c 2003-10-09 18:47:31.000000000 +0200 +++ linux-2.4.22-grsec/net/netsyms.c 2003-10-09 19:13:26.000000000 +0200 @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef CONFIG_HIPPI #include #endif @@ -613,6 +614,20 @@ EXPORT_SYMBOL(softnet_data); +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE) +#if !defined (CONFIG_IPV6_MODULE) && !defined (CONFIG_KHTTPD) && !defined (CONFIG_KHTTPD_MODULE) +EXPORT_SYMBOL(tcp_v4_lookup_listener); +#endif +#if !defined(CONFIG_IP_NF_MATCH_OWNER) && !defined(CONFIG_IP_NF_MATCH_OWNER_MODULE) +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); +EXPORT_SYMBOL(udp_v4_lookup); +#endif +#endif + +#ifdef CONFIG_UNIX_MODULE +EXPORT_SYMBOL(gr_handle_chroot_unix); +#endif + #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) #include EXPORT_SYMBOL(wireless_send_event); diff -urN linux-2.4.22/net/socket.c linux-2.4.22/net/socket.c --- linux-2.4.22/net/socket.c 2003-09-01 22:19:08.000000000 -0400 +++ linux-2.4.22/net/socket.c 2003-09-02 19:29:42.000000000 -0400 @@ -85,6 +85,12 @@ #include #include +extern void gr_attach_curr_ip(const struct sock *sk); +extern int gr_handle_sock_all(const int family, const int type, + const int protocol); +extern int gr_handle_sock_server(const struct sockaddr *sck); +extern int gr_handle_sock_client(const struct sockaddr *sck); + static int sock_no_open(struct inode *irrelevant, struct file *dontcare); static ssize_t sock_read(struct file *file, char *buf, size_t size, loff_t *ppos); @@ -699,6 +711,7 @@ int sock_close(struct inode *inode, struct file *filp) { + struct socket *sock; /* * It was possible the inode is NULL we were * closing an unfinished socket. @@ -709,8 +722,21 @@ printk(KERN_DEBUG "sock_close: NULL inode\n"); return 0; } + sock = socki_lookup(inode); + sock_fasync(-1, filp, 0); + +#ifdef CONFIG_GRKERNSEC + if (unlikely(current->used_accept && sock->sk && + (sock->sk->protocol == IPPROTO_TCP) && + (sock->sk->daddr == current->curr_ip))) { + current->used_accept = 0; + current->curr_ip = 0; + } +#endif + sock_release(socki_lookup(inode)); + return 0; } @@ -903,6 +929,13 @@ int retval; struct socket *sock; +#ifdef CONFIG_GRKERNSEC + if (gr_handle_sock_all(family, type, protocol)) { + retval = -EACCES; + goto out; + } +#endif + retval = sock_create(family, type, protocol, &sock); if (retval < 0) goto out; @@ -998,12 +1034,23 @@ { struct socket *sock; char address[MAX_SOCK_ADDR]; + struct sockaddr * sck; int err; if((sock = sockfd_lookup(fd,&err))!=NULL) { - if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) + if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { +#ifdef CONFIG_GRKERNSEC + sck = (struct sockaddr *) address; + + if (gr_handle_sock_server(sck)) { + sockfd_put(sock); + return -EACCES; + } +#endif + err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen); + } sockfd_put(sock); } return err; @@ -1079,6 +1129,10 @@ if ((err = sock_map_fd(newsock)) < 0) goto out_release; +#ifdef CONFIG_GRKERNSEC + gr_attach_curr_ip(newsock->sk); +#endif + out_put: sockfd_put(sock); out: @@ -1106,6 +1158,7 @@ { struct socket *sock; char address[MAX_SOCK_ADDR]; + struct sockaddr * sck; int err; sock = sockfd_lookup(fd, &err); @@ -1114,6 +1167,19 @@ err = move_addr_to_kernel(uservaddr, addrlen, address); if (err < 0) goto out_put; + +#ifdef CONFIG_GRKERNSEC + sck = (struct sockaddr *) address; + + if (gr_handle_sock_client(sck)) { + err = -EACCES; + goto out_put; + } + + if (sock->sk->protocol == IPPROTO_TCP) + current->used_connect = 1; +#endif + err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, sock->file->f_flags); out_put: @@ -1333,6 +1404,14 @@ err=sock->ops->shutdown(sock, how); sockfd_put(sock); } + +#ifdef CONFIG_GRKERNSEC + if (likely(!err && current->used_accept)) { + current->used_accept = 0; + current->curr_ip = 0; + } +#endif + return err; } diff -urN linux-2.4.22/net/unix/af_unix.c linux-2.4.22-grsec/net/unix/af_unix.c --- linux-2.4.22/net/unix/af_unix.c 2003-10-09 18:47:35.000000000 +0200 +++ linux-2.4.22-grsec/net/unix/af_unix.c 2003-10-09 19:13:26.000000000 +0200 @@ -109,6 +109,7 @@ #include #include #include +#include #include @@ -622,6 +623,15 @@ if (u) { struct dentry *dentry; dentry = u->protinfo.af_unix.dentry; + +#ifdef CONFIG_GRKERNSEC + if (!gr_handle_chroot_unix(u->peercred.pid)) { + err = -EPERM; + sock_put(u); + goto fail; + } +#endif + if (dentry) UPDATE_ATIME(dentry->d_inode); } else @@ -740,6 +748,10 @@ goto out_unlock; } +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX + sk->peercred.pid = current->pid; +#endif + list = &unix_socket_table[addr->hash]; } else { list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; @@ -866,6 +893,9 @@ int st; int err; long timeo; +#ifdef CONFIG_GRKERNSEC + struct task_struct *p, **htable; +#endif err = unix_mkname(sunaddr, addr_len, &hash); if (err < 0) @@ -989,6 +1019,17 @@ /* Set credentials */ sk->peercred = other->peercred; +#ifdef CONFIG_GRKERNSEC + read_lock(&tasklist_lock); + htable = &pidhash[pid_hashfn(other->peercred.pid)]; + for (p = *htable; p && p->pid != other->peercred.pid; p = p->pidhash_next); + if (p) { + p->curr_ip = current->curr_ip; + p->used_accept = 1; + } + read_unlock(&tasklist_lock); +#endif + sock_hold(newsk); unix_peer(sk)=newsk; sock->state=SS_CONNECTED;