Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 22210 Details for
Bug 35819
Proposed patches for ppc-sources-2.4.22-r4
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
40_grsecurity-2.0-rc3
40_grsecurity-2.0-rc3 (text/plain), 544.24 KB, created by
David Holm (RETIRED)
on 2003-12-14 12:13:18 UTC
(
hide
)
Description:
40_grsecurity-2.0-rc3
Filename:
MIME Type:
Creator:
David Holm (RETIRED)
Created:
2003-12-14 12:13:18 UTC
Size:
544.24 KB
patch
obsolete
>diff -Naur linux-2.4.22-ppc-dev.orig/Documentation/Configure.help linux-2.4.22-ppc-dev/Documentation/Configure.help >--- linux-2.4.22-ppc-dev.orig/Documentation/Configure.help 2003-09-14 14:07:49.000000000 +0200 >+++ linux-2.4.22-ppc-dev/Documentation/Configure.help 2003-09-14 14:07:40.000000000 +0200 >@@ -2725,6 +2725,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 >@@ -22283,6 +22297,871 @@ > > "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. >+ >+Additional security levels >+CONFIG_GRKERNSEC_LOW >+ >+ Low additional security >+ ----------------------------------------------------------------------- >+ If you choose this option, several of the grsecurity options will >+ be enabled that will give you greater protection against a number >+ of attacks, while assuring that none of your software will have any >+ conflicts with the additional security measures. If you run a lot of >+ unusual software, or you are having problems with the higher security >+ levels, you should say Y here. With this option, the following features >+ are enabled: >+ >+ linking restrictions >+ fifo restrictions >+ random pids >+ enforcing nproc on execve() >+ restricted dmesg >+ random ip ids >+ enforced chdir("/") on chroot >+ >+ Medium additional security >+ ----------------------------------------------------------------------- >+ If you say Y here, several features in addition to those included in the >+ low additional security level will be enabled. These features provide >+ even more security to your system, though in rare cases they may >+ be incompatible with very old or poorly written software. If you >+ enable this option, make sure that your auth service (identd) is >+ running as gid 10 (usually group wheel). With this option the following >+ features (in addition to those provided in the low additional security >+ level) will be enabled: >+ >+ random tcp source ports >+ altered ping ids >+ failed fork logging >+ time change logging >+ signal logging >+ deny mounts in chroot >+ deny double chrooting >+ deny sysctl writes in chroot >+ deny mknod in chroot >+ deny access to abstract AF_UNIX sockets out of chroot >+ deny pivot_root in chroot >+ denied writes of /dev/kmem, /dev/mem, and /dev/port >+ /proc restrictions with special gid set to 10 (usually wheel) >+ address space layout randomization >+ >+ High additional security >+ ---------------------------------------------------------------------- >+ If you say Y here, many of the features of grsecurity will be enabled, >+ that will protect you against many kinds of attacks against >+ your system. The heightened security comes at a cost of an >+ increased chance of incompatibilities with rare software on your >+ machine. It is highly recommended that you view >+ <http://grsecurity.net/features.htm> and read about each option. Since >+ this security level enabled PaX, you should also view >+ <http://pageexec.virtualave.net> and read about the PaX project. While >+ you are there, download chpax.c and run chpax -p on binaries that cause >+ problems with PaX. Also remember that since the /proc restrictions are >+ enabled, you must run your identd as group wheel (gid 10). >+ This security level enables the following features in addition to those >+ listed in the low and medium security levels: >+ >+ additional /proc restrictions >+ chmod restrictions in chroot >+ no signals, ptrace, or viewing processes outside of chroot >+ capability restrictions in chroot >+ deny fchdir out of chroot >+ priority restrictions in chroot >+ segmentation-based implementation of PaX >+ mprotect restrictions >+ removal of /proc/<pid>/[maps|mem] >+ kernel stack randomization >+ mount/unmount/remount logging >+ kernel symbol hiding >+ >+Customized additional security >+CONFIG_GRKERNSEC_CUSTOM >+ If you say Y here, you will be able to configure every grsecurity >+ option, which allows you to enable many more features that aren't >+ covered in the basic security levels. These additional features include >+ TPE, socket restrictions, and the sysctl system for grsecurity. It is >+ advised that you read through the help for each option to determine its >+ usefulness in your situation. >+ >+Enforce non-executable pages >+CONFIG_GRKERNSEC_PAX_NOEXEC >+ By design some architectures do not allow for protecting memory >+ pages against execution or even if they do, Linux does not make >+ use of this feature. In practice this means that if a page is >+ readable (such as the stack or heap) it is also executable. >+ >+ There is a well known exploit technique that makes use of this >+ fact and a common programming mistake where an attacker can >+ introduce code of his choice somewhere in the attacked program's >+ memory (typically the stack or the heap) and then execute it. >+ >+ If the attacked program was running with different (typically >+ higher) privileges than that of the attacker, then he can elevate >+ his own privilege level (e.g. get a root shell, write to files for >+ which he does not have write access to, etc). >+ >+ Enabling this option will let you choose from various features >+ that prevent the injection and execution of 'foreign' code in >+ a program. >+ >+ This will also break programs that rely on the old behaviour and >+ expect that dynamically allocated memory via the malloc() family >+ of functions is executable (which it is not). Notable examples >+ are the XFree86 4.x server, the java runtime and wine. >+ >+ NOTE: you can use the 'chpax' utility to enable/disable this >+ feature on a per file basis. chpax is available at >+ <http://pageexec.virtualave.net> >+ >+Paging based non-executable pages >+CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ This implementation is based on the paging feature of the CPU. >+ On i386 it has a variable performance impact on applications >+ depending on their memory usage pattern. You should carefully >+ test your applications before using this feature in production. >+ On alpha, parisc, sparc and sparc64 there is no performance >+ impact. On ppc there is a slight performance impact. >+ >+Segmentation based non-executable pages >+CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ This implementation is based on the segmentation feature of the >+ CPU and has little performance impact, however applications will >+ be limited to a 1.5 GB address space instead of the normal 3 GB. >+ >+Emulate trampolines >+CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ There are some programs and libraries that for one reason or >+ another attempt to execute special small code snippets from >+ non-executable memory pages. Most notable examples are the >+ signal handler return code generated by the kernel itself and >+ the GCC trampolines. >+ >+ If you enabled CONFIG_GRKERNSEC_PAX_PAGEEXEC or >+ CONFIG_GRKERNSEC_PAX_SEGMEXEC then such programs will no longer >+ work under your kernel. >+ >+ As a remedy you can say Y here and use the 'chpax' utility to >+ enable trampoline emulation for the affected programs yet still >+ have the protection provided by the non-executable pages. >+ >+ On parisc and ppc you MUST enable this option and EMUSIGRT as >+ well, otherwise your system will not even boot. >+ >+ Alternatively you can say N here and use the 'chpax' utility >+ to disable CONFIG_GRKERNSEC_PAX_PAGEEXEC and >+ CONFIG_GRKERNSEC_PAX_SEGMEXEC for the affected files. >+ >+ NOTE: enabling this feature *may* open up a loophole in the >+ protection provided by non-executable pages that an attacker >+ could abuse. Therefore the best solution is to not have any >+ files on your system that would require this option. This can >+ be achieved by not using libc5 (which relies on the kernel >+ signal handler return code) and not using or rewriting programs >+ that make use of the nested function implementation of GCC. >+ Skilled users can just fix GCC itself so that it implements >+ nested function calls in a way that does not interfere with PaX. >+ >+Automatically emulate sigreturn trampolines >+CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ Enabling this option will have the kernel automatically detect >+ and emulate signal return trampolines executing on the stack >+ that would otherwise lead to task termination. >+ >+ This solution is intended as a temporary one for users with >+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17, >+ Modula-3 runtime, etc) or executables linked to such, basically >+ everything that does not specify its own SA_RESTORER function in >+ normal executable memory like glibc 2.1+ does. >+ >+ On parisc and ppc you MUST enable this option, otherwise your >+ system will not even boot. >+ >+ NOTE: this feature cannot be disabled on a per executable basis >+ and since it *does* open up a loophole in the protection provided >+ by non-executable pages, the best solution is to not have any >+ files on your system that would require this option. >+ >+Restrict mprotect() >+CONFIG_GRKERNSEC_PAX_MPROTECT >+ Enabling this option will prevent programs from >+ - changing the executable status of memory pages that were >+ not originally created as executable, >+ - making read-only executable pages writable again, >+ - creating executable pages from anonymous memory. >+ >+ You should say Y here to complete the protection provided by >+ the enforcement of non-executable pages. >+ >+ NOTE: you can use the 'chpax' utility to control this >+ feature on a per file basis. chpax is available at >+ <http://pageexec.virtualave.net> >+ >+Disallow ELF text relocations >+CONFIG_GRKERNSEC_PAX_NOELFRELOCS >+ Non-executable pages and mprotect() restrictions are effective >+ in preventing the introduction of new executable code into an >+ attacked task's address space. There remain only two venues >+ for this kind of attack: if the attacker can execute already >+ existing code in the attacked task then he can either have it >+ create and mmap() a file containing his code or have it mmap() >+ an already existing ELF library that does not have position >+ independent code in it and use mprotect() on it to make it >+ writable and copy his code there. While protecting against >+ the former approach is beyond PaX, the latter can be prevented >+ by having only PIC ELF libraries on one's system (which do not >+ need to relocate their code). If you are sure this is your case, >+ then enable this option otherwise be careful as you may not even >+ be able to boot or log on your system (for example, some PAM >+ modules are erroneously compiled as non-PIC by default). >+ >+ NOTE: if you are using dynamic ELF executables (as suggested >+ when using ASLR) then you must have made sure that you linked >+ your files using the PIC version of crt1 (the et_dyn.zip package >+ referenced there has already been updated to support this). >+ >+Enforce non-executable kernel pages >+CONFIG_GRKERNSEC_PAX_KERNEXEC >+ This is the kernel land equivalent of PAGEEXEC and MPROTECT, >+ that is, enabling this option will make it harder to inject >+ and execute 'foreign' code in kernel memory itself. >+ >+Address Space Layout Randomization >+CONFIG_GRKERNSEC_PAX_ASLR >+ Many if not most exploit techniques rely on the knowledge of >+ certain addresses in the attacked program. The following options >+ will allow the kernel to apply a certain amount of randomization >+ to specific parts of the program thereby forcing an attacker to >+ guess them in most cases. Any failed guess will most likely crash >+ the attacked program which allows the kernel to detect such attempts >+ and react on them. PaX itself provides no reaction mechanisms, >+ instead it is strongly encouraged that you make use of grsecurity's >+ built-in crash detection features or develop one yourself. >+ >+ By saying Y here you can choose to randomize the following areas: >+ - top of the task's kernel stack >+ - top of the task's userland stack >+ - base address for mmap() requests that do not specify one >+ (this includes all libraries) >+ - base address of the main executable >+ >+ It is strongly recommended to say Y here as address space layout >+ randomization has negligible impact on performance yet it provides >+ a very effective protection. >+ >+ NOTE: you can use the 'chpax' utility to control most of these features >+ on a per file basis. >+ >+Randomize kernel stack base >+CONFIG_GRKERNSEC_PAX_RANDKSTACK >+ By saying Y here the kernel will randomize every task's kernel >+ stack on every system call. This will not only force an attacker >+ to guess it but also prevent him from making use of possible >+ leaked information about it. >+ >+ Since the kernel stack is a rather scarce resource, randomization >+ may cause unexpected stack overflows, therefore you should very >+ carefully test your system. Note that once enabled in the kernel >+ configuration, this feature cannot be disabled on a per file basis. >+ >+Randomize user stack base >+CONFIG_GRKERNSEC_PAX_RANDUSTACK >+ By saying Y here the kernel will randomize every task's userland >+ stack. The randomization is done in two steps where the second >+ one may apply a big amount of shift to the top of the stack and >+ cause problems for programs that want to use lots of memory (more >+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is). >+ For this reason the second step can be controlled by 'chpax' on >+ a per file basis. >+ >+Randomize ET_EXEC base >+CONFIG_GRKERNSEC_PAX_RANDEXEC >+ By saying Y here the kernel will randomize the base address of normal >+ ET_EXEC ELF executables as well. This is accomplished by mapping the >+ executable in memory in a special way which also allows for detecting >+ attackers who attempt to execute its code for their purposes. Since >+ this special mapping causes performance degradation and the attack >+ detection may create false alarms as well, you should carefully test >+ your executables when this feature is enabled. >+ >+ This solution is intended only as a temporary one until you relink >+ your programs as a dynamic ELF file. >+ >+ NOTE: you can use the 'chpax' utility to control this feature >+ on a per file basis. >+ >+Allow ELF ET_EXEC text relocations >+CONFIG_GRKERNSEC_PAX_ETEXECRELOCS >+ On some architectures like the alpha there are incorrectly >+ created applications that require text relocations and would >+ not work without enabling this option. If you are an alpha >+ user, you should enable this option and disable it once you >+ have made sure that none of your applications need it. >+ >+Automatically emulate ELF PLT >+CONFIG_GRKERNSEC_PAX_EMUPLT >+ Enabling this option will have the kernel automatically detect >+ and emulate the Procedure Linkage Table entries in ELF files. >+ On some architectures such entries are in writable memory, and >+ become non-executable leading to task termination. Therefore >+ it is mandatory that you enable this option on alpha, parisc, ppc, >+ sparc and sparc64, otherwise your system would not even boot. >+ >+ NOTE: this feature *does* open up a loophole in the protection >+ provided by the non-executable pages, therefore the proper >+ solution is to modify the toolchain to produce a PLT that does >+ not need to be writable. >+ >+ >+Randomize mmap() base >+CONFIG_GRKERNSEC_PAX_RANDMMAP >+ By saying Y here the kernel will use a randomized base address for >+ mmap() requests that do not specify one themselves. As a result >+ all dynamically loaded libraries will appear at random addresses >+ and therefore be harder to exploit by a technique where an attacker >+ attempts to execute library code for his purposes (e.g. spawn a >+ shell from an exploited program that is running at an elevated >+ privilege level). >+ >+ Furthermore, if a program is relinked as a dynamic ELF file, its >+ base address will be randomized as well, completing the full >+ randomization of the address space layout. Attacking such programs >+ becomes a guess game. You can find an example of doing this at >+ <http://pageexec.virtualave.net/et_dyn.zip> and practical samples at >+ <http://www.grsecurity.net/grsec-gcc-specs.tar.gz> . >+ >+ NOTE: you can use the 'chpax' utility to control this feature >+ on a per file basis. >+ >+Deny writing to /dev/kmem, /dev/mem, and /dev/port >+CONFIG_GRKERNSEC_KMEM >+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to >+ be written to via mmap or otherwise to modify the running kernel. >+ /dev/port will also not be allowed to be opened. If you have module >+ support disabled, enabling this will close up four ways that are >+ currently used to insert malicious code into the running kernel. >+ Even with all these features enabled, we still highly recommend that >+ you use the ACL system, as it is still possible for an attacker to >+ modify the running kernel through privileged I/O granted by ioperm/iopl. >+ If you are not using XFree86, you may be able to stop this additional >+ case by enabling the 'Disable privileged I/O' option. Though nothing >+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem, >+ but only to video memory, which is the only writing we allow in this >+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will >+ not be allowed to mprotect it with PROT_WRITE later. >+ Enabling this feature could make certain apps like VMWare stop working, >+ as they need to write to other locations in /dev/mem. >+ It is highly recommended that you say Y here if you meet all the >+ conditions above. >+ >+Disable privileged I/O >+CONFIG_GRKERNSEC_IO >+ If you say Y here, all ioperm and iopl calls will return an error. >+ Ioperm and iopl can be used to modify the running kernel. >+ Unfortunately, some programs need this access to operate properly, >+ the most notable of which are XFree86 and hwclock. hwclock can be >+ remedied by having RTC support in the kernel, so CONFIG_RTC is >+ enabled if this option is enabled, to ensure that hwclock operates >+ correctly. XFree86 still will not operate correctly with this option >+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86 >+ and you still want to protect your kernel against modification, >+ use the ACL system. >+ >+Hide kernel symbols >+CONFIG_GRKERNSEC_HIDESYM >+ If you say Y here, getting information on loaded modules, and >+ displaying all kernel symbols through a syscall will be restricted >+ to users with CAP_SYS_MODULE. This option is only effective >+ provided the following conditions are met: >+ 1) The kernel using grsecurity is not precompiled by some distribution >+ 2) You are using the ACL system and hiding other files such as your >+ kernel image and System.map >+ 3) You have the additional /proc restrictions enabled, which removes >+ /proc/kcore >+ If the above conditions are met, this option will aid to provide a >+ useful protection against local and remote kernel exploitation of >+ overflows and arbitrary read/write vulnerabilities. >+ >+/proc/<pid>/ipaddr support >+CONFIG_GRKERNSEC_PROC_IPADDR >+ If you say Y here, a new entry will be added to each /proc/<pid> >+ 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. >+ >+Proc Restrictions >+CONFIG_GRKERNSEC_PROC >+ If you say Y here, the permissions of the /proc filesystem >+ will be altered to enhance system security and privacy. Depending >+ upon the options you choose, you can either restrict users to see >+ only the processes they themselves run, or choose a group that can >+ view all processes and files normally restricted to root if you choose >+ the "restrict to user only" option. NOTE: If you're running identd as >+ a non-root user, you will have to run it as the group you specify here. >+ >+Restrict /proc to user only >+CONFIG_GRKERNSEC_PROC_USER >+ If you say Y here, non-root users will only be able to view their own >+ processes, and restricts them from viewing network-related information, >+ and viewing kernel symbol and module information. >+ >+Restrict /proc to user and group >+CONFIG_GRKERNSEC_PROC_USERGROUP >+ If you say Y here, you will be able to select a group that will be >+ able to view all processes, network-related information, and >+ kernel and symbol information. This option is useful if you want >+ to run identd as a non-root user. >+ >+Remove addresses from /proc/pid/[maps|stat] >+CONFIG_GRKERNSEC_PROC_MEMMAP >+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will >+ give no information about the addresses of its mappings if >+ PaX features that rely on random addresses are enabled on the task. >+ If you use PaX it is greatly recommended that you say Y here as it >+ closes up a hole that makes the full ASLR useless for suid >+ binaries. >+ >+Additional proc restrictions >+CONFIG_GRKERNSEC_PROC_ADD >+ If you say Y here, additional restrictions will be placed on >+ /proc that keep normal users from viewing cpu and device information. >+ >+Dmesg(8) Restriction >+CONFIG_GRKERNSEC_DMESG >+ If you say Y here, non-root users will not be able to use dmesg(8) >+ to view up to the last 4kb of messages in the kernel's log buffer. >+ If the sysctl option is enabled, a sysctl option with name "dmesg" is >+ created. >+ >+Linking restrictions >+CONFIG_GRKERNSEC_LINK >+ If you say Y here, /tmp race exploits will be prevented, since users >+ will no longer be able to follow symlinks owned by other users in >+ world-writable +t directories (i.e. /tmp), unless the owner of the >+ symlink is the owner of the directory. users will also not be >+ able to hardlink to files they do not own. If the sysctl option is >+ enabled, a sysctl option with name "linking_restrictions" is created. >+ >+FIFO restrictions >+CONFIG_GRKERNSEC_FIFO >+ If you say Y here, users will not be able to write to FIFOs they don't >+ own in world-writable +t directories (i.e. /tmp), unless the owner of >+ the FIFO is the same owner of the directory it's held in. If the sysctl >+ option is enabled, a sysctl option with name "fifo_restrictions" is >+ created. >+ >+Enforce RLIMIT_NPROC on execs >+CONFIG_GRKERNSEC_EXECVE >+ If you say Y here, users with a resource limit on processes will >+ have the value checked during execve() calls. The current system >+ only checks the system limit during fork() calls. If the sysctl option >+ is enabled, a sysctl option with name "execve_limiting" is created. >+ >+Single group for auditing >+CONFIG_GRKERNSEC_AUDIT_GROUP >+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features >+ will only operate on a group you specify. This option is recommended >+ if you only want to watch certain users instead of having a large >+ amount of logs from the entire system. If the sysctl option is enabled, >+ a sysctl option with name "audit_group" is created. >+ >+GID for auditing >+CONFIG_GRKERNSEC_AUDIT_GID >+ Here you can choose the GID that will be the target of kernel auditing. >+ Remember to add the users you want to log 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 >+ "audit_gid" is created. >+ >+Chdir logging >+CONFIG_GRKERNSEC_AUDIT_CHDIR >+ If you say Y here, all chdir() calls will be logged. If the sysctl >+ option is enabled, a sysctl option with name "audit_chdir" is created. >+ >+(Un)Mount logging >+CONFIG_GRKERNSEC_AUDIT_MOUNT >+ If you say Y here, all mounts and unmounts will be logged. If the >+ sysctl option is enabled, a sysctl option with name "audit_mount" is >+ created. >+ >+IPC logging >+CONFIG_GRKERNSEC_AUDIT_IPC >+ If you say Y here, creation and removal of message queues, semaphores, >+ and shared memory will be logged. If the sysctl option is enabled, a >+ sysctl option with name "audit_ipc" is created. >+ >+Exec logging >+CONFIG_GRKERNSEC_EXECLOG >+ If you say Y here, all execve() calls will be logged (since the >+ other exec*() calls are frontends to execve(), all execution >+ will be logged). Useful for shell-servers that like to keep track >+ of their users. If the sysctl option is enabled, a sysctl option with >+ name "exec_logging" is created. >+ WARNING: This option when enabled will produce a LOT of logs, especially >+ on an active system. >+ >+Resource logging >+CONFIG_GRKERNSEC_RESLOG >+ If you say Y here, all attempts to overstep resource limits will >+ be logged with the resource name, the requested size, and the current >+ limit. It is highly recommended that you say Y here. >+ >+Signal logging >+CONFIG_GRKERNSEC_SIGNAL >+ If you say Y here, certain important signals will be logged, such as >+ SIGSEGV, which will as a result inform you of when a error in a program >+ occurred, which in some cases could mean a possible exploit attempt. >+ If the sysctl option is enabled, a sysctl option with name >+ "signal_logging" is created. >+ >+Fork failure logging >+CONFIG_GRKERNSEC_FORKFAIL >+ If you say Y here, all failed fork() attempts will be logged. >+ This could suggest a fork bomb, or someone attempting to overstep >+ their process limit. If the sysctl option is enabled, a sysctl option >+ with name "forkfail_logging" is created. >+ >+Time change logging >+CONFIG_GRKERNSEC_TIME >+ If you say Y here, any changes of the system clock will be logged. >+ If the sysctl option is enabled, a sysctl option with name >+ "timechange_logging" is created. >+ >+Chroot jail restrictions >+CONFIG_GRKERNSEC_CHROOT >+ If you say Y here, you will be able to choose several options that will >+ make breaking out of a chrooted jail much more difficult. If you >+ encounter no software incompatibilities with the following options, it >+ is recommended that you enable each one. >+ >+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. >+ >+Randomized PIDs >+CONFIG_GRKERNSEC_RANDPID >+ If you say Y here, all PIDs created on the system will be >+ pseudo-randomly generated. This is extremely effective along >+ with the /proc restrictions to disallow an attacker from guessing >+ pids of daemons, etc. PIDs are also used in some cases as part >+ of a naming system for temporary files, so this option would keep >+ those filenames from being predicted as well. We also use code >+ to make sure that PID numbers aren't reused too soon. If the sysctl >+ option is enabled, a sysctl option with name "rand_pids" is created. >+ >+Larger entropy pools >+CONFIG_GRKERNSEC_RANDNET >+ If you say Y here, the entropy pools used for many features of Linux >+ and grsecurity will be doubled in size. Since several grsecurity >+ features use additional randomness, it is recommended that you say Y >+ here. Saying Y here has a similar effect as modifying >+ /proc/sys/kernel/random/poolsize. >+ >+Truly random TCP ISN selection >+CONFIG_GRKERNSEC_RANDISN >+ If you say Y here, Linux's default selection of TCP Initial Sequence >+ Numbers (ISNs) will be replaced with that of OpenBSD. Linux uses >+ an MD4 hash based on the connection plus a time value to create the >+ ISN, while OpenBSD's selection is random. If the sysctl option is >+ enabled, a sysctl option with name "rand_isns" is created. >+ >+Randomized IP IDs >+CONFIG_GRKERNSEC_RANDID >+ If you say Y here, all the id field on all outgoing packets >+ will be randomized. This hinders os fingerprinters and >+ keeps your machine from being used as a bounce for an untraceable >+ portscan. Ids are used for fragmented packets, fragments belonging >+ to the same packet have the same id. By default linux only >+ increments the id value on each packet sent to an individual host. >+ We use a port of the OpenBSD random ip id code to achieve the >+ randomness, while keeping the possibility of id duplicates to >+ near none. If the sysctl option is enabled, a sysctl option with name >+ "rand_ip_ids" is created. >+ >+Randomized TCP source ports >+CONFIG_GRKERNSEC_RANDSRC >+ If you say Y here, situations where a source port is generated on the >+ fly for the TCP protocol (ie. with connect() ) will be altered so that >+ the source port is generated at random, instead of a simple incrementing >+ algorithm. If the sysctl option is enabled, a sysctl option with name >+ "rand_tcp_src_ports" is created. >+ >+Randomized RPC XIDs >+CONFIG_GRKERNSEC_RANDRPC >+ If you say Y here, the method of determining XIDs for RPC requests will >+ be randomized, instead of using linux's default behavior of simply >+ incrementing the XID. If you want your RPC connections to be more >+ secure, say Y here. If the sysctl option is enabled, a sysctl option >+ with name "rand_rpc" 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. >+ >+Sysctl support >+CONFIG_GRKERNSEC_SYSCTL >+ If you say Y here, you will be able to change the options that >+ grsecurity runs with at bootup, without having to recompile your >+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity >+ to enable (1) or disable (0) various features. All the sysctl entries >+ are mutable until the "grsec_lock" entry is set to a non-zero value. >+ All features are disabled by default. Please note that this option could >+ reduce the effectiveness of the added security of this patch if an ACL >+ system is not put in place. Your init scripts should be read-only, and >+ root should not have access to adding modules or performing raw i/o >+ operations. All options should be set at startup, and the grsec_lock >+ entry should be set to a non-zero value after all the options are set. >+ *THIS IS EXTREMELY IMPORTANT* >+ >+Number of burst messages >+CONFIG_GRKERNSEC_FLOODBURST >+ This option allows you to choose the maximum number of messages allowed >+ within the flood time interval you chose in a separate option. The >+ default should be suitable for most people, however if you find that >+ many of your logs are being interpreted as flooding, you may want to >+ raise this value. >+ >+Seconds in between log messages >+CONFIG_GRKERNSEC_FLOODTIME >+ This option allows you to enforce the number of seconds between >+ grsecurity log messages. The default should be suitable for most >+ people, however, if you choose to change it, choose a value small enough >+ to allow informative logs to be produced, but large enough to >+ prevent flooding. >+ >+Hide kernel processes >+CONFIG_GRKERNSEC_ACL_HIDEKERN >+ If you say Y here, when the ACL system is enabled via gradm -E, >+ an additional ACL will be passed to the kernel that hides all kernel >+ processes. These processes will only be viewable by the authenticated >+ admin, or processes that have viewing access set. >+ >+Maximum tries before password lockout >+CONFIG_GRKERNSEC_ACL_MAXTRIES >+ This option enforces the maximum number of times a user can attempt >+ to authorize themselves with the grsecurity ACL system before being >+ denied the ability to attempt authorization again for a specified time. >+ The lower the number, the harder it will be to brute-force a password. >+ >+Time to wait after max password tries, in seconds >+CONFIG_GRKERNSEC_ACL_TIMEOUT >+ This option specifies the time the user must wait after attempting to >+ authorize to the ACL system with the maximum number of invalid >+ passwords. The higher the number, the harder it will be to brute-force >+ a password. >+ > Disable data cache > CONFIG_DCACHE_DISABLE > This option allows you to run the kernel with data cache disabled. >diff -Naur linux-2.4.22-ppc-dev.orig/Makefile linux-2.4.22-ppc-dev/Makefile >--- linux-2.4.22-ppc-dev.orig/Makefile 2003-09-14 14:06:51.000000000 +0200 >+++ linux-2.4.22-ppc-dev/Makefile 2003-09-14 14:07:40.000000000 +0200 >@@ -126,9 +126,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 := >@@ -270,7 +271,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 $< >@@ -289,6 +290,7 @@ > $(CORE_FILES) \ > $(DRIVERS) \ > $(NETWORKS) \ >+ $(GRSECURITY) \ > $(LIBS) \ > --end-group \ > -o vmlinux >diff -Naur linux-2.4.22-ppc-dev.orig/arch/alpha/config.in linux-2.4.22-ppc-dev/arch/alpha/config.in >--- linux-2.4.22-ppc-dev.orig/arch/alpha/config.in 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/alpha/config.in 2003-09-14 14:07:40.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 -Naur linux-2.4.22-ppc-dev.orig/arch/alpha/kernel/osf_sys.c linux-2.4.22-ppc-dev/arch/alpha/kernel/osf_sys.c >--- linux-2.4.22-ppc-dev.orig/arch/alpha/kernel/osf_sys.c 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/alpha/kernel/osf_sys.c 2003-09-14 14:07:40.000000000 +0200 >@@ -33,6 +33,7 @@ > #include <linux/file.h> > #include <linux/types.h> > #include <linux/ipc.h> >+#include <linux/grsecurity.h> > > #include <asm/fpu.h> > #include <asm/io.h> >@@ -230,6 +231,11 @@ > struct file *file = NULL; > unsigned long ret = -EBADF; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > #if 0 > if (flags & (_MAP_HASSEMAPHORE | _MAP_INHERIT | _MAP_UNALIGNED)) > printk("%s: unimplemented OSF mmap flags %04lx\n", >@@ -240,6 +246,13 @@ > if (!file) > goto out; > } >+ >+ if(gr_handle_mmap(file, prot)) { >+ fput(file); >+ ret = -EACCES; >+ goto out; >+ } >+ > flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); > down_write(¤t->mm->mmap_sem); > ret = do_mmap(file, addr, len, prot, flags, off); >@@ -1357,6 +1370,10 @@ > merely specific addresses, but regions of memory -- perhaps > this feature should be incorporated into all ports? */ > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp) >+#endif >+ > if (addr) { > addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); > if (addr != -ENOMEM) >@@ -1364,8 +1381,15 @@ > } > > /* Next, try allocating at TASK_UNMAPPED_BASE. */ >- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE), >- len, limit); >+ >+ addr = TASK_UNMAPPED_BASE; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ if (current->flags & PF_PAX_RANDMMAP) >+ addr += current->mm->delta_mmap; >+#endif >+ >+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); > if (addr != -ENOMEM) > return addr; > >diff -Naur linux-2.4.22-ppc-dev.orig/arch/alpha/kernel/ptrace.c linux-2.4.22-ppc-dev/arch/alpha/kernel/ptrace.c >--- linux-2.4.22-ppc-dev.orig/arch/alpha/kernel/ptrace.c 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/alpha/kernel/ptrace.c 2003-09-14 14:07:40.000000000 +0200 >@@ -13,6 +13,7 @@ > #include <linux/ptrace.h> > #include <linux/user.h> > #include <linux/slab.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/pgtable.h> >@@ -275,6 +276,10 @@ > read_unlock(&tasklist_lock); > if (!child) > goto out_notsk; >+ >+ if(gr_handle_ptrace(child, request)) >+ goto out; >+ > if (request == PTRACE_ATTACH) { > ret = ptrace_attach(child); > goto out; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/alpha/mm/fault.c linux-2.4.22-ppc-dev/arch/alpha/mm/fault.c >--- linux-2.4.22-ppc-dev.orig/arch/alpha/mm/fault.c 2003-09-14 14:06:51.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/alpha/mm/fault.c 2003-09-14 14:07:40.000000000 +0200 >@@ -53,6 +53,139 @@ > __reload_thread(¤t->thread); > } > >+/* >+ * PaX: decide what to do with offenders (regs->pc = fault address) >+ * >+ * returns 1 when task should be killed >+ * 2 when patched PLT trampoline was detected >+ * 3 when unpatched PLT trampoline was detected >+ * 4 when legitimate ET_EXEC was detected >+ */ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+static int pax_handle_fetch_fault(struct pt_regs *regs) >+{ >+ int err; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (current->flags & PF_PAX_RANDEXEC) { >+ if (regs->pc >= current->mm->start_code && >+ regs->pc < current->mm->end_code) >+ { >+ if (regs->r26 == regs->pc) >+ return 1; >+ regs->pc += current->mm->delta_exec; >+ return 4; >+ } >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ do { /* PaX: patched PLT emulation #1 */ >+ unsigned int ldah, ldq, jmp; >+ >+ err = get_user(ldah, (unsigned int *)regs->pc); >+ err |= get_user(ldq, (unsigned int *)(regs->pc+4)); >+ err |= get_user(jmp, (unsigned int *)(regs->pc+8)); >+ >+ if (err) >+ break; >+ >+ if ((ldah & 0xFFFF0000U)== 0x277B0000U && >+ (ldq & 0xFFFF0000U) == 0xA77B0000U && >+ jmp == 0x6BFB0000U) >+ { >+ unsigned long r27, addr; >+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; >+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL; >+ >+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); >+ err = get_user(r27, (unsigned long*)addr); >+ if (err) >+ break; >+ >+ regs->r27 = r27; >+ regs->pc = r27; >+ return 2; >+ } >+ } while (0); >+ >+ do { /* PaX: patched PLT emulation #2 */ >+ unsigned int ldah, lda, br; >+ >+ err = get_user(ldah, (unsigned int *)regs->pc); >+ err |= get_user(lda, (unsigned int *)(regs->pc+4)); >+ err |= get_user(br, (unsigned int *)(regs->pc+8)); >+ >+ if (err) >+ break; >+ >+ if ((ldah & 0xFFFF0000U)== 0x277B0000U && >+ (lda & 0xFFFF0000U) == 0xA77B0000U && >+ (br & 0xFFE00000U) == 0xC3E00000U) >+ { >+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL; >+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; >+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL; >+ >+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); >+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); >+ return 2; >+ } >+ } while (0); >+ >+ do { /* PaX: unpatched PLT emulation */ >+ unsigned int br; >+ >+ err = get_user(br, (unsigned int *)regs->pc); >+ >+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) { >+ unsigned int br2, ldq, nop, jmp; >+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver; >+ >+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); >+ err = get_user(br2, (unsigned int *)addr); >+ err |= get_user(ldq, (unsigned int *)(addr+4)); >+ err |= get_user(nop, (unsigned int *)(addr+8)); >+ err |= get_user(jmp, (unsigned int *)(addr+12)); >+ err |= get_user(resolver, (unsigned long *)(addr+16)); >+ >+ if (err) >+ break; >+ >+ if (br2 == 0xC3600000U && >+ ldq == 0xA77B000CU && >+ nop == 0x47FF041FU && >+ jmp == 0x6B7B0000U) >+ { >+ regs->r28 = regs->pc+4; >+ regs->r27 = addr+16; >+ regs->pc = resolver; >+ return 3; >+ } >+ } >+ } while (0); >+#endif >+ >+ return 1; >+} >+ >+void pax_report_insns(void *pc) >+{ >+ unsigned long i; >+ >+ printk(KERN_ERR "PAX: bytes at PC: "); >+ for (i = 0; i < 5; i++) { >+ unsigned int c; >+ if (get_user(c, (unsigned int*)pc+i)) { >+ printk("<invalid address>."); >+ break; >+ } >+ printk("%08x ", c); >+ } >+ printk("\n"); >+} >+#endif >+ > > /* > * This routine handles page faults. It determines the address, >@@ -133,8 +266,32 @@ > good_area: > info.si_code = SEGV_ACCERR; > if (cause < 0) { >- if (!(vma->vm_flags & VM_EXEC)) >+ if (!(vma->vm_flags & VM_EXEC)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (!(current->flags & PF_PAX_PAGEEXEC) || address != regs->pc) >+ goto bad_area; >+ >+ up_read(&mm->mmap_sem); >+ switch(pax_handle_fetch_fault(regs)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ case 2: >+ case 3: >+ return; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ case 4: >+ return; >+#endif >+ } >+ pax_report_fault(regs, (void*)regs->pc, (void*)rdusp()); >+ do_exit(SIGKILL); >+#else > goto bad_area; >+#endif >+ } > } else if (!cause) { > /* Allow reads even for write-only mappings */ > if (!(vma->vm_flags & (VM_READ | VM_WRITE))) >diff -Naur linux-2.4.22-ppc-dev.orig/arch/arm/config.in linux-2.4.22-ppc-dev/arch/arm/config.in >--- linux-2.4.22-ppc-dev.orig/arch/arm/config.in 2003-09-14 14:04:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/arm/config.in 2003-09-14 14:07:40.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 -Naur linux-2.4.22-ppc-dev.orig/arch/cris/config.in linux-2.4.22-ppc-dev/arch/cris/config.in >--- linux-2.4.22-ppc-dev.orig/arch/cris/config.in 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/cris/config.in 2003-09-14 14:07:40.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 -Naur linux-2.4.22-ppc-dev.orig/arch/i386/Makefile linux-2.4.22-ppc-dev/arch/i386/Makefile >--- linux-2.4.22-ppc-dev.orig/arch/i386/Makefile 2003-09-14 14:03:57.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/Makefile 2003-09-14 14:07:40.000000000 +0200 >@@ -114,6 +114,9 @@ > > MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot > >+arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE >+ $(CPP) -C -P -I$(HPATH) -imacros $(HPATH)/linux/config.h -imacros $(HPATH)/asm-i386/segment.h -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds >+ > vmlinux: arch/i386/vmlinux.lds > > FORCE: ; >@@ -150,6 +153,7 @@ > @$(MAKEBOOT) clean > > archmrproper: >+ rm -f arch/i386/vmlinux.lds > > archdep: > @$(MAKEBOOT) dep >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/config.in linux-2.4.22-ppc-dev/arch/i386/config.in >--- linux-2.4.22-ppc-dev.orig/arch/i386/config.in 2003-09-14 14:03:57.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/config.in 2003-09-14 14:07:40.000000000 +0200 >@@ -480,3 +480,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 -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/apm.c linux-2.4.22-ppc-dev/arch/i386/kernel/apm.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/apm.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/apm.c 2003-09-14 14:07:40.000000000 +0200 >@@ -614,7 +614,7 @@ > __asm__ __volatile__(APM_DO_ZERO_SEGS > "pushl %%edi\n\t" > "pushl %%ebp\n\t" >- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" >+ "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" > "setc %%al\n\t" > "popl %%ebp\n\t" > "popl %%edi\n\t" >@@ -666,7 +666,7 @@ > __asm__ __volatile__(APM_DO_ZERO_SEGS > "pushl %%edi\n\t" > "pushl %%ebp\n\t" >- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" >+ "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" > "setc %%bl\n\t" > "popl %%ebp\n\t" > "popl %%edi\n\t" >@@ -1985,6 +1985,12 @@ > __va((unsigned long)0x40 << 4)); > _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4)); > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ set_base(gdt2[APM_40 >> 3], >+ __va((unsigned long)0x40 << 4)); >+ _set_limit((char *)&gdt2[APM_40 >> 3], 4095 - (0x40 << 4)); >+#endif >+ > apm_bios_entry.offset = apm_info.bios.offset; > apm_bios_entry.segment = APM_CS; > set_base(gdt[APM_CS >> 3], >@@ -1993,6 +1999,16 @@ > __va((unsigned long)apm_info.bios.cseg_16 << 4)); > set_base(gdt[APM_DS >> 3], > __va((unsigned long)apm_info.bios.dseg << 4)); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ set_base(gdt2[APM_CS >> 3], >+ __va((unsigned long)apm_info.bios.cseg << 4)); >+ set_base(gdt2[APM_CS_16 >> 3], >+ __va((unsigned long)apm_info.bios.cseg_16 << 4)); >+ set_base(gdt2[APM_DS >> 3], >+ __va((unsigned long)apm_info.bios.dseg << 4)); >+#endif >+ > #ifndef APM_RELAX_SEGMENTS > if (apm_info.bios.version == 0x100) { > #endif >@@ -2002,6 +2018,13 @@ > _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1); > /* For the DEC Hinote Ultra CT475 (and others?) */ > _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ _set_limit((char *)&gdt2[APM_CS >> 3], 64 * 1024 - 1); >+ _set_limit((char *)&gdt2[APM_CS_16 >> 3], 64 * 1024 - 1); >+ _set_limit((char *)&gdt2[APM_DS >> 3], 64 * 1024 - 1); >+#endif >+ > #ifndef APM_RELAX_SEGMENTS > } else { > _set_limit((char *)&gdt[APM_CS >> 3], >@@ -2010,6 +2033,16 @@ > (apm_info.bios.cseg_16_len - 1) & 0xffff); > _set_limit((char *)&gdt[APM_DS >> 3], > (apm_info.bios.dseg_len - 1) & 0xffff); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ _set_limit((char *)&gdt2[APM_CS >> 3], >+ (apm_info.bios.cseg_len - 1) & 0xffff); >+ _set_limit((char *)&gdt2[APM_CS_16 >> 3], >+ (apm_info.bios.cseg_16_len - 1) & 0xffff); >+ _set_limit((char *)&gdt2[APM_DS >> 3], >+ (apm_info.bios.dseg_len - 1) & 0xffff); >+#endif >+ > } > #endif > >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/entry.S linux-2.4.22-ppc-dev/arch/i386/kernel/entry.S >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/entry.S 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/entry.S 2003-09-14 14:07:40.000000000 +0200 >@@ -209,6 +209,17 @@ > jae badsys > call *SYMBOL_NAME(sys_call_table)(,%eax,4) > movl %eax,EAX(%esp) # save the return value >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK >+ cli # need_resched and signals atomic test >+ cmpl $0,need_resched(%ebx) >+ jne reschedule >+ cmpl $0,sigpending(%ebx) >+ jne signal_return >+ call SYMBOL_NAME(pax_randomize_kstack) >+ jmp restore_all >+#endif >+ > ENTRY(ret_from_sys_call) > cli # need_resched and signals atomic test > cmpl $0,need_resched(%ebx) >@@ -389,8 +400,56 @@ > jmp error_code > > ENTRY(page_fault) >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ ALIGN >+ pushl $ SYMBOL_NAME(pax_do_page_fault) >+#else > pushl $ SYMBOL_NAME(do_page_fault) >+#endif >+ >+#ifndef CONFIG_GRKERNSEC_PAX_EMUTRAMP > jmp error_code >+#else >+ pushl %ds >+ pushl %eax >+ xorl %eax,%eax >+ pushl %ebp >+ pushl %edi >+ pushl %esi >+ pushl %edx >+ decl %eax # eax = -1 >+ pushl %ecx >+ pushl %ebx >+ cld >+ movl %es,%ecx >+ movl ORIG_EAX(%esp), %esi # get the error code >+ movl ES(%esp), %edi # get the function address >+ movl %eax, ORIG_EAX(%esp) >+ movl %ecx, ES(%esp) >+ movl %esp,%edx >+ pushl %esi # push the error code >+ pushl %edx # push the pt_regs pointer >+ movl $(__KERNEL_DS),%edx >+ movl %edx,%ds >+ movl %edx,%es >+ GET_CURRENT(%ebx) >+ call *%edi >+ addl $8,%esp >+ decl %eax >+ jnz ret_from_exception >+ >+ popl %ebx >+ popl %ecx >+ popl %edx >+ popl %esi >+ popl %edi >+ popl %ebp >+ popl %eax >+ popl %ds >+ popl %es >+ addl $4,%esp >+ jmp system_call >+#endif > > ENTRY(machine_check) > pushl $0 >@@ -402,7 +461,7 @@ > pushl $ SYMBOL_NAME(do_spurious_interrupt_bug) > jmp error_code > >-.data >+.section .rodata, "a" > ENTRY(sys_call_table) > .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ > .long SYMBOL_NAME(sys_exit) >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/head.S linux-2.4.22-ppc-dev/arch/i386/kernel/head.S >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/head.S 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/head.S 2003-09-14 14:07:40.000000000 +0200 >@@ -41,6 +41,7 @@ > * > * On entry, %esi points to the real-mode code as a 32-bit pointer. > */ >+.global startup_32 > startup_32: > /* > * Set segments to known values >@@ -86,7 +87,7 @@ > PRESENT+RW+USER */ > 2: stosl > add $0x1000,%eax >- cmp $empty_zero_page-__PAGE_OFFSET,%edi >+ cmp $0x00c00007,%eax > jne 2b > > /* >@@ -100,9 +101,19 @@ > movl %eax,%cr0 /* ..and set paging (PG) bit */ > jmp 1f /* flush the prefetch-queue */ > 1: >+ >+#if !defined(CONFIG_GRKERNSEC_PAX_KERNEXEC) || defined(CONFIG_SMP) >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ orw %bx,%bx >+ jz 1f >+#endif >+ > movl $1f,%eax > jmp *%eax /* make sure eip is relocated */ > 1: >+#endif >+ > /* Set up the stack pointer */ > lss stack_start,%esp > >@@ -121,7 +132,7 @@ > */ > xorl %eax,%eax > movl $ SYMBOL_NAME(__bss_start),%edi >- movl $ SYMBOL_NAME(_end),%ecx >+ movl $ SYMBOL_NAME(__bss_end),%ecx > subl %edi,%ecx > rep > stosb >@@ -272,8 +283,6 @@ > jmp L6 # main should never return here, but > # just in case, we know what happens. > >-ready: .byte 0 >- > /* > * We depend on ET to be correct. This checks for 287/387. > */ >@@ -319,13 +328,6 @@ > jne rp_sidt > ret > >-ENTRY(stack_start) >- .long SYMBOL_NAME(init_task_union)+8192 >- .long __KERNEL_DS >- >-/* This is the default interrupt "handler" :-) */ >-int_msg: >- .asciz "Unknown interrupt\n" > ALIGN > ignore_int: > cld >@@ -347,6 +349,18 @@ > popl %eax > iret > >+.data >+ready: .byte 0 >+ >+ENTRY(stack_start) >+ .long SYMBOL_NAME(init_task_union)+8192 >+ .long __KERNEL_DS >+ >+.section .rodata,"a" >+/* This is the default interrupt "handler" :-) */ >+int_msg: >+ .asciz "Unknown interrupt\n" >+ > /* > * The interrupt descriptor table has room for 256 idt's, > * the global descriptor table is dependent on the number >@@ -372,41 +386,58 @@ > SYMBOL_NAME(gdt): > .long SYMBOL_NAME(gdt_table) > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+.globl SYMBOL_NAME(gdt2) >+ .word 0 >+gdt_descr2: >+ .word GDT_ENTRIES*8-1 >+SYMBOL_NAME(gdt2): >+ .long SYMBOL_NAME(gdt_table2) >+#endif >+ > /* > * This is initialized to create an identity-mapping at 0-8M (for bootup > * purposes) and another mapping of the 0-8M area at virtual address > * PAGE_OFFSET. > */ >-.org 0x1000 >+.section .data.swapper_pg_dir,"a" > ENTRY(swapper_pg_dir) >- .long 0x00102007 >- .long 0x00103007 >- .fill BOOT_USER_PGD_PTRS-2,4,0 >+ .long pg0-__PAGE_OFFSET+7 >+ .long pg1-__PAGE_OFFSET+7 >+ .long pg2-__PAGE_OFFSET+7 >+ .fill BOOT_USER_PGD_PTRS-3,4,0 > /* default: 766 entries */ >- .long 0x00102007 >- .long 0x00103007 >+ .long pg0-__PAGE_OFFSET+7 >+ .long pg1-__PAGE_OFFSET+7 >+ .long pg2-__PAGE_OFFSET+7 > /* default: 254 entries */ >- .fill BOOT_KERNEL_PGD_PTRS-2,4,0 >+ .fill BOOT_KERNEL_PGD_PTRS-3,4,0 > > /* > * The page tables are initialized to only 8MB here - the final page > * tables are set up later depending on memory size. > */ >-.org 0x2000 >+.section .data.pg0,"a" > ENTRY(pg0) >+ .fill 1024,4,0 > >-.org 0x3000 >+.section .data.pg1,"a" > ENTRY(pg1) >+ .fill 1024,4,0 >+ >+.section .data.pg2,"a" >+ENTRY(pg2) >+ .fill 1024,4,0 > > /* > * empty_zero_page must immediately follow the page tables ! (The > * initialization loop counts until empty_zero_page) > */ >- >-.org 0x4000 >+.section .data.empty_zero_page,"a" > ENTRY(empty_zero_page) >+ .fill 1024,4,0 > >-.org 0x5000 >+.text > > /* > * Real beginning of normal "text" segment >@@ -419,7 +450,7 @@ > * in the text section because it has alignment requirements > * that we cannot fulfill any other way. > */ >-.data >+.section .rodata,"a" > > ALIGN > /* >@@ -430,19 +461,55 @@ > */ > ENTRY(gdt_table) > .quad 0x0000000000000000 /* NULL descriptor */ >- .quad 0x0000000000000000 /* not used */ >- .quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ >- .quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ >- .quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */ >- .quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */ >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ .quad 0x00cf9b000000ffff /* 0x08 kernel 4GB code at 0x00000000 */ >+ .quad 0xc0cf9b400000ffff /* 0x10 kernel 4GB code at 0xc0400000 */ >+#else >+ .quad 0x0000000000000000 /* not used */ >+ .quad 0x00cf9b000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ >+#endif >+ >+ .quad 0x00cf93000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ >+ .quad 0x00cffb000000ffff /* 0x23 user 4GB code at 0x00000000 */ >+ .quad 0x00cff3000000ffff /* 0x2b user 4GB data at 0x00000000 */ >+ .quad 0x0000000000000000 /* not used */ >+ .quad 0x0000000000000000 /* not used */ >+ /* >+ * The APM segments have byte granularity and their bases >+ * and limits are set at run time. >+ */ >+ .quad 0x0040930000000000 /* 0x40 APM set up for bad BIOS's */ >+ .quad 0x00409b0000000000 /* 0x48 APM CS code */ >+ .quad 0x00009b0000000000 /* 0x50 APM CS 16 code (16 bit) */ >+ .quad 0x0040930000000000 /* 0x58 APM DS data */ >+ .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ENTRY(gdt_table2) >+ .quad 0x0000000000000000 /* NULL descriptor */ >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ .quad 0x00cf9b000000ffff /* 0x08 kernel 4GB code at 0x00000000 */ >+ .quad 0xc0cf9b400000ffff /* 0x10 kernel 4GB code at 0xc0400000 */ >+#else >+ .quad 0x0000000000000000 /* not used */ >+ .quad 0x00cf9b000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ >+#endif >+ >+ .quad 0x00cf93000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ >+ .quad 0x60c5fb000000ffff /* 0x23 user 1.5GB code at 0x60000000 */ >+ .quad 0x00c5f3000000ffff /* 0x2b user 1.5GB data at 0x00000000 */ >+ > .quad 0x0000000000000000 /* not used */ > .quad 0x0000000000000000 /* not used */ > /* > * The APM segments have byte granularity and their bases > * and limits are set at run time. > */ >- .quad 0x0040920000000000 /* 0x40 APM set up for bad BIOS's */ >- .quad 0x00409a0000000000 /* 0x48 APM CS code */ >- .quad 0x00009a0000000000 /* 0x50 APM CS 16 code (16 bit) */ >- .quad 0x0040920000000000 /* 0x58 APM DS data */ >+ .quad 0x0040930000000000 /* 0x40 APM set up for bad BIOS's */ >+ .quad 0x00409b0000000000 /* 0x48 APM CS code */ >+ .quad 0x00009b0000000000 /* 0x50 APM CS 16 code (16 bit) */ >+ .quad 0x0040930000000000 /* 0x58 APM DS data */ > .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ >+#endif >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/i386_ksyms.c linux-2.4.22-ppc-dev/arch/i386/kernel/i386_ksyms.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/i386_ksyms.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/i386_ksyms.c 2003-09-14 14:07:40.000000000 +0200 >@@ -73,6 +73,9 @@ > EXPORT_SYMBOL(get_cmos_time); > EXPORT_SYMBOL(apm_info); > EXPORT_SYMBOL(gdt); >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+EXPORT_SYMBOL(gdt2); >+#endif > EXPORT_SYMBOL(empty_zero_page); > > #ifdef CONFIG_DEBUG_IOVIRT >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/ioport.c linux-2.4.22-ppc-dev/arch/i386/kernel/ioport.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/ioport.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/ioport.c 2003-09-14 14:07:40.000000000 +0200 >@@ -14,6 +14,7 @@ > #include <linux/smp.h> > #include <linux/smp_lock.h> > #include <linux/stddef.h> >+#include <linux/grsecurity.h> > > /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ > static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value) >@@ -59,8 +60,16 @@ > > if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32)) > return -EINVAL; >+#ifdef CONFIG_GRKERNSEC_IO >+ if (turn_on) { >+ gr_handle_ioperm(); >+#else > if (turn_on && !capable(CAP_SYS_RAWIO)) >+#endif > return -EPERM; >+#ifdef CONFIG_GRKERNSEC_IO >+ } >+#endif > /* > * If it's the first ioperm() call in this thread's lifetime, set the > * IO bitmap up. ioperm() is much less timing critical than clone(), >@@ -109,8 +118,13 @@ > return -EINVAL; > /* Trying to gain more privileges? */ > if (level > old) { >+#ifdef CONFIG_GRKERNSEC_IO >+ gr_handle_iopl(); >+ return -EPERM; >+#else > if (!capable(CAP_SYS_RAWIO)) > return -EPERM; >+#endif > } > regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12); > return 0; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/ldt.c linux-2.4.22-ppc-dev/arch/i386/kernel/ldt.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/ldt.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/ldt.c 2003-09-14 14:07:40.000000000 +0200 >@@ -122,6 +122,13 @@ > } > } > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((current->flags & PF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) { >+ error = -EINVAL; >+ goto out_unlock; >+ } >+#endif >+ > entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | > (ldt_info.limit & 0x0ffff); > entry_2 = (ldt_info.base_addr & 0xff000000) | >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/pci-pc.c linux-2.4.22-ppc-dev/arch/i386/kernel/pci-pc.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/pci-pc.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/pci-pc.c 2003-09-14 14:07:40.000000000 +0200 >@@ -17,6 +17,7 @@ > #include <asm/io.h> > #include <asm/smp.h> > #include <asm/smpboot.h> >+#include <asm/desc.h> > > #include "pci-i386.h" > >@@ -575,10 +576,16 @@ > * the array there. > */ > >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+#define __FLAT_KERNEL_CS 0x08 >+#else >+#define __FLAT_KERNEL_CS __KERNEL_CS >+#endif >+ > static struct { > unsigned long address; > unsigned short segment; >-} bios32_indirect = { 0, __KERNEL_CS }; >+} bios32_indirect = { 0, __FLAT_KERNEL_CS }; > > /* > * Returns the entry point for the given service, NULL on error >@@ -619,7 +626,9 @@ > static struct { > unsigned long address; > unsigned short segment; >-} pci_indirect = { 0, __KERNEL_CS }; >+} pci_indirect = { 0, __FLAT_KERNEL_CS }; >+ >+#undef __FLAT_KERNEL_CS > > static int pci_bios_present; > >@@ -1456,6 +1465,7 @@ > if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) > pcibios_sort(); > #endif >+ > } > > char * __devinit pcibios_setup(char *str) >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/process.c linux-2.4.22-ppc-dev/arch/i386/kernel/process.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/process.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/process.c 2003-09-14 14:07:40.000000000 +0200 >@@ -585,7 +585,11 @@ > { > struct pt_regs * childregs; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK >+ childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p - sizeof(unsigned long))) - 1; >+#else > childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1; >+#endif > struct_cpy(childregs, regs); > childregs->eax = 0; > childregs->esp = esp; >@@ -646,6 +650,16 @@ > dump->u_fpvalid = dump_fpu (regs, &dump->i387); > } > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+void pax_switch_segments(struct task_struct * tsk) >+{ >+ if (tsk->flags & PF_PAX_SEGMEXEC) >+ __asm__ __volatile__("lgdt %0": "=m" (gdt_descr2)); >+ else >+ __asm__ __volatile__("lgdt %0": "=m" (gdt_descr)); >+} >+#endif >+ > /* > * This special macro can be used to load a debugging register > */ >@@ -685,6 +699,10 @@ > > unlazy_fpu(prev_p); > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ pax_switch_segments(next_p); >+#endif >+ > /* > * Reload esp0, LDT and the page table pointer: > */ >@@ -825,3 +843,25 @@ > } > #undef last_sched > #undef first_sched >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDKSTACK >+asmlinkage void pax_randomize_kstack(void) >+{ >+ struct tss_struct *tss = init_tss + smp_processor_id(); >+ unsigned long time; >+ >+ rdtscl(time); >+ >+ /* P4 seems to return a 0 LSB, ignore it */ >+#ifdef CONFIG_MPENTIUM4 >+ time &= 0x3EUL; >+ time <<= 1; >+#else >+ time &= 0x1FUL; >+ time <<= 2; >+#endif >+ >+ current->thread.esp0 ^= time; >+ tss->esp0 = current->thread.esp0; >+} >+#endif >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/ptrace.c linux-2.4.22-ppc-dev/arch/i386/kernel/ptrace.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/ptrace.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/ptrace.c 2003-09-14 14:07:40.000000000 +0200 >@@ -13,6 +13,7 @@ > #include <linux/errno.h> > #include <linux/ptrace.h> > #include <linux/user.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/pgtable.h> >@@ -177,6 +178,9 @@ > if (pid == 1) /* you may not mess with init */ > goto out_tsk; > >+ if(gr_handle_ptrace(child, request)) >+ goto out_tsk; >+ > if (request == PTRACE_ATTACH) { > ret = ptrace_attach(child); > goto out_tsk; >@@ -256,6 +260,17 @@ > if(addr < (long) &dummy->u_debugreg[4] && > ((unsigned long) data) >= TASK_SIZE-3) break; > >+#ifdef CONFIG_GRKERNSEC >+ if(addr >= (long) &dummy->u_debugreg[0] && >+ addr <= (long) &dummy->u_debugreg[3]){ >+ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2; >+ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3; >+ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3; >+ if((type & 1) && (data & align)) >+ break; >+ } >+#endif >+ > if(addr == (long) &dummy->u_debugreg[7]) { > data &= ~DR_CONTROL_RESERVED; > for(i=0; i<4; i++) >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/setup.c linux-2.4.22-ppc-dev/arch/i386/kernel/setup.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/setup.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/setup.c 2003-09-14 14:07:40.000000000 +0200 >@@ -3126,7 +3126,7 @@ > set_tss_desc(nr,t); > gdt_table[__TSS(nr)].b &= 0xfffffdff; > load_TR(nr); >- load_LDT(&init_mm); >+ _load_LDT(&init_mm); > > /* > * Clear all 6 debug registers: >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/sys_i386.c linux-2.4.22-ppc-dev/arch/i386/kernel/sys_i386.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/sys_i386.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/sys_i386.c 2003-09-14 14:07:40.000000000 +0200 >@@ -18,6 +18,7 @@ > #include <linux/mman.h> > #include <linux/file.h> > #include <linux/utsname.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/ipc.h> >@@ -48,6 +49,11 @@ > int error = -EBADF; > struct file * file = NULL; > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); > if (!(flags & MAP_ANONYMOUS)) { > file = fget(fd); >@@ -55,8 +61,14 @@ > goto out; > } > >+ if(gr_handle_mmap(file, prot)) { >+ fput(file); >+ error = -EACCES; >+ goto out; >+ } >+ > down_write(¤t->mm->mmap_sem); >- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); >+ error = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT); > up_write(¤t->mm->mmap_sem); > > if (file) >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/trampoline.S linux-2.4.22-ppc-dev/arch/i386/kernel/trampoline.S >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/trampoline.S 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/trampoline.S 2003-09-14 14:07:40.000000000 +0200 >@@ -54,7 +54,7 @@ > lmsw %ax # into protected mode > jmp flush_instr > flush_instr: >- ljmpl $__KERNEL_CS, $0x00100000 >+ ljmpl $__KERNEL_CS, $SYMBOL_NAME(startup_32)-__PAGE_OFFSET > # jump to startup_32 in arch/i386/kernel/head.S > > idt_48: >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/kernel/traps.c linux-2.4.22-ppc-dev/arch/i386/kernel/traps.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/kernel/traps.c 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/kernel/traps.c 2003-09-14 14:07:40.000000000 +0200 >@@ -228,14 +228,23 @@ > show_stack((unsigned long*)esp); > > printk("\nCode: "); >+ >+#ifndef CONFIG_GRKERNSEC_PAX_KERNEXEC > if(regs->eip < PAGE_OFFSET) > goto bad; >+#endif > > for(i=0;i<20;i++) > { > unsigned char c; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) { >+#else > if(__get_user(c, &((unsigned char*)regs->eip)[i])) { > bad: >+#endif >+ > printk(" Bad EIP value."); > break; > } >@@ -258,8 +267,13 @@ > > eip = regs->eip; > >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ eip += __KERNEL_TEXT_OFFSET; >+#else > if (eip < PAGE_OFFSET) > goto no_bug; >+#endif >+ > if (__get_user(ud2, (unsigned short *)eip)) > goto no_bug; > if (ud2 != 0x0b0f) >@@ -267,7 +281,13 @@ > if (__get_user(line, (unsigned short *)(eip + 2))) > goto bug; > if (__get_user(file, (char **)(eip + 4)) || >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ __get_user(c, file + __KERNEL_TEXT_OFFSET)) >+#else > (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) >+#endif >+ > file = "<bad filename>"; > > printk("kernel BUG at %s:%d!\n", file, line); >@@ -417,6 +437,18 @@ > gp_in_kernel: > { > unsigned long fixup; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ if ((regs->xcs & 0xFFFF) == __KERNEL_CS) { >+ if (current->curr_ip) >+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: task %s:%d, uid/euid: %u/%u, may have attempted to execute invalid code at %08lx\n", >+ NIPQUAD(current->curr_ip), current->comm, current->pid, current->uid, current->euid, regs->eip); >+ else >+ printk(KERN_ERR "PAX: task %s:%d, uid/euid: %u/%u, may have attempted to execute invalid code at %08lx\n", >+ current->comm, current->pid, current->uid, current->euid, regs->eip); >+ } >+#endif >+ > fixup = search_exception_table(regs->eip); > if (fixup) { > regs->eip = fixup; >@@ -527,13 +559,12 @@ > { > unsigned int condition; > struct task_struct *tsk = current; >- unsigned long eip = regs->eip; > siginfo_t info; > > __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); > > /* If the user set TF, it's simplest to clear it right away. */ >- if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK)) >+ if (!(regs->xcs & 3) && (regs->eflags & TF_MASK) && !(regs->eflags & VM_MASK)) > goto clear_TF; > > /* Mask out spurious debug traps due to lazy DR7 setting */ >@@ -855,11 +886,55 @@ > void set_tss_desc(unsigned int n, void *addr) > { > _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ _set_tssldt_desc(gdt_table2+__TSS(n), (int)addr, 235, 0x89); >+#endif >+ >+} >+ >+void __set_ldt_desc(unsigned int n, void *addr, unsigned int size) >+{ >+ _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82); >+#endif >+ > } > > void set_ldt_desc(unsigned int n, void *addr, unsigned int size) > { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ unsigned long temp, cr3; >+ pgd_t* pgd; >+ pmd_t* pmd; >+ >+ asm("movl %%cr3,%0":"=r" (cr3)); >+ for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) { >+ pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp); >+ pmd = pmd_offset(pgd, temp); >+ set_pmd(pmd, __pmd(pmd_val(*pmd) | _PAGE_RW)); >+ } >+ __flush_tlb_all(); >+#endif >+ > _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82); >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ for (temp = __KERNEL_TEXT_OFFSET; temp < __KERNEL_TEXT_OFFSET + 0x00400000UL; temp += (1UL << PMD_SHIFT)) { >+ pgd = (pgd_t *)__va(cr3) + __pgd_offset(temp); >+ pmd = pmd_offset(pgd, temp); >+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); >+ } >+ flush_tlb_all(); >+#endif >+ > } > > #ifdef CONFIG_X86_VISWS_APIC >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/mm/fault.c linux-2.4.22-ppc-dev/arch/i386/mm/fault.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/mm/fault.c 2003-09-14 14:06:51.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/mm/fault.c 2003-09-14 14:07:40.000000000 +0200 >@@ -4,6 +4,7 @@ > * Copyright (C) 1995 Linus Torvalds > */ > >+#include <linux/config.h> > #include <linux/signal.h> > #include <linux/sched.h> > #include <linux/kernel.h> >@@ -19,6 +20,8 @@ > #include <linux/init.h> > #include <linux/tty.h> > #include <linux/vt_kern.h> /* For unblank_screen() */ >+#include <linux/unistd.h> >+#include <linux/compiler.h> > > #include <asm/system.h> > #include <asm/uaccess.h> >@@ -128,6 +131,10 @@ > asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); > extern unsigned long idt; > >+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) >+static int pax_handle_fetch_fault(struct pt_regs *regs); >+#endif >+ > /* > * This routine handles page faults. It determines the address, > * and the problem, and then passes it off to one of the appropriate >@@ -138,23 +145,31 @@ > * bit 1 == 0 means read, 1 means write > * bit 2 == 0 means kernel, 1 means user-mode > */ >-asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+static int do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address) >+#else >+asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long error_code) >+#endif > { > struct task_struct *tsk; > struct mm_struct *mm; > struct vm_area_struct * vma, * prev_vma; >+#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC > unsigned long address; >+#endif > unsigned long page; > unsigned long fixup; > int write; > siginfo_t info; > >+#ifndef CONFIG_GRKERNSEC_PAX_PAGEEXEC > /* get the address */ > __asm__("movl %%cr2,%0":"=r" (address)); > > /* It's safe to allow irq's after cr2 has been saved */ > if (regs->eflags & X86_EFLAGS_IF) > local_irq_enable(); >+#endif > > tsk = current; > >@@ -260,7 +275,7 @@ > tsk->thread.screen_bitmap |= 1 << bit; > } > up_read(&mm->mmap_sem); >- return; >+ return 0; > > /* > * Something tried to access memory that isn't in our memory map.. >@@ -271,6 +286,39 @@ > > /* User mode accesses just cause a SIGSEGV */ > if (error_code & 4) { >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if (current->flags & PF_PAX_SEGMEXEC) { >+ >+#if defined(CONFIG_GRKERNSEC_PAX_EMUTRAMP) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if ((error_code == 4) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) { >+ switch (pax_handle_fetch_fault(regs)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ case 5: >+ return 0; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ case 4: >+ return 0; >+ case 3: >+ case 2: >+ return 1; >+#endif >+ >+ case 1: >+ default: >+ } >+ } >+#endif >+ >+ if (address >= SEGMEXEC_TASK_SIZE) { >+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp); >+ do_exit(SIGKILL); >+ } >+ } >+#endif >+ > tsk->thread.cr2 = address; > tsk->thread.error_code = error_code; > tsk->thread.trap_no = 14; >@@ -279,7 +327,7 @@ > /* info.si_code has been set above */ > info.si_addr = (void *)address; > force_sig_info(SIGSEGV, &info, tsk); >- return; >+ return 0; > } > > /* >@@ -292,7 +340,7 @@ > > if (nr == 6) { > do_invalid_op(regs, 0); >- return; >+ return 0; > } > } > >@@ -300,7 +348,7 @@ > /* Are we prepared to handle this kernel fault? */ > if ((fixup = search_exception_table(regs->eip)) != 0) { > regs->eip = fixup; >- return; >+ return 0; > } > > /* >@@ -312,6 +360,18 @@ > > if (address < PAGE_SIZE) > printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ else if (init_mm.start_code + __KERNEL_TEXT_OFFSET <= address && address < init_mm.end_code + __KERNEL_TEXT_OFFSET) { >+ if (tsk->curr_ip) >+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", >+ NIPQUAD(tsk->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid); >+ else >+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", >+ tsk->comm, tsk->pid, tsk->uid, tsk->euid); >+ } >+#endif >+ > else > printk(KERN_ALERT "Unable to handle kernel paging request"); > printk(" at virtual address %08lx\n",address); >@@ -364,7 +424,7 @@ > /* Kernel mode? Handle exceptions or die */ > if (!(error_code & 4)) > goto no_context; >- return; >+ return 0; > > vmalloc_fault: > { >@@ -397,6 +457,337 @@ > pte_k = pte_offset(pmd_k, address); > if (!pte_present(*pte_k)) > goto no_context; >- return; >+ return 0; >+ } >+} >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+/* PaX: called with the page_table_lock spinlock held */ >+static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address) >+{ >+ pgd_t *pgd; >+ pmd_t *pmd; >+ >+ pgd = pgd_offset(mm, address); >+ if (!pgd || !pgd_present(*pgd)) >+ return 0; >+ pmd = pmd_offset(pgd, address); >+ if (!pmd || !pmd_present(*pmd)) >+ return 0; >+ return pte_offset(pmd, address); >+} >+#endif >+ >+/* >+ * PaX: decide what to do with offenders (regs->eip = fault address) >+ * >+ * returns 1 when task should be killed >+ * 2 when sigreturn trampoline was detected >+ * 3 when rt_sigreturn trampoline was detected >+ * 4 when gcc trampoline was detected >+ * 5 when legitimate ET_EXEC was detected >+ */ >+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) >+static int pax_handle_fetch_fault(struct pt_regs *regs) >+{ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4}; >+#endif >+ int err; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (current->flags & PF_PAX_RANDEXEC) { >+ unsigned long esp_4; >+ if (regs->eip >= current->mm->start_code && >+ regs->eip < current->mm->end_code) >+ { >+ err = get_user(esp_4, (unsigned long*)(regs->esp-4UL)); >+ if (err || esp_4 == regs->eip) >+ return 1; >+ regs->eip += current->mm->delta_exec; >+ return 5; >+ } >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ >+#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ if (!(current->flags & PF_PAX_EMUTRAMP)) >+ return 1; >+#endif >+ >+ do { /* PaX: sigreturn emulation */ >+ unsigned char pop, mov; >+ unsigned short sys; >+ unsigned long nr; >+ >+ err = get_user(pop, (unsigned char *)(regs->eip)); >+ err |= get_user(mov, (unsigned char *)(regs->eip + 1)); >+ err |= get_user(nr, (unsigned long *)(regs->eip + 2)); >+ err |= get_user(sys, (unsigned short *)(regs->eip + 6)); >+ >+ if (err) >+ break; >+ >+ if (pop == 0x58 && >+ mov == 0xb8 && >+ nr == __NR_sigreturn && >+ sys == 0x80cd) >+ { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ int sig; >+ struct k_sigaction *ka; >+ __sighandler_t handler; >+ >+ if (get_user(sig, (int *)regs->esp)) >+ return 1; >+ if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP) >+ return 1; >+ ka = ¤t->sig->action[sig-1]; >+ handler = ka->sa.sa_handler; >+ if (handler == SIG_DFL || handler == SIG_IGN) { >+ if (!(current->flags & PF_PAX_EMUTRAMP)) >+ return 1; >+ } else if (!(ka->sa.sa_flags & SA_SIGINFO)) >+ return 1; >+#endif >+ >+ regs->esp += 4; >+ regs->eax = nr; >+ regs->eip += 8; >+ return 2; >+ } >+ } while (0); >+ >+ do { /* PaX: rt_sigreturn emulation */ >+ unsigned char mov; >+ unsigned short sys; >+ unsigned long nr; >+ >+ err = get_user(mov, (unsigned char *)(regs->eip)); >+ err |= get_user(nr, (unsigned long *)(regs->eip + 1)); >+ err |= get_user(sys, (unsigned short *)(regs->eip + 5)); >+ >+ if (err) >+ break; >+ >+ if (mov == 0xb8 && >+ nr == __NR_rt_sigreturn && >+ sys == 0x80cd) >+ { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ int sig; >+ struct k_sigaction *ka; >+ __sighandler_t handler; >+ >+ if (get_user(sig, (int *)regs->esp)) >+ return 1; >+ if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP) >+ return 1; >+ ka = ¤t->sig->action[sig-1]; >+ handler = ka->sa.sa_handler; >+ if (handler == SIG_DFL || handler == SIG_IGN) { >+ if (!(current->flags & PF_PAX_EMUTRAMP)) >+ return 1; >+ } else if (ka->sa.sa_flags & SA_SIGINFO) >+ return 1; >+#endif >+ >+ regs->eax = nr; >+ regs->eip += 7; >+ return 3; >+ } >+ } while (0); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ if (!(current->flags & PF_PAX_EMUTRAMP)) >+ return 1; >+#endif >+ >+ do { /* PaX: gcc trampoline emulation #1 */ >+ unsigned char mov1, mov2; >+ unsigned short jmp; >+ unsigned long addr1, addr2, ret; >+ unsigned short call; >+ >+ err = get_user(mov1, (unsigned char *)regs->eip); >+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1)); >+ err |= get_user(mov2, (unsigned char *)(regs->eip + 5)); >+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6)); >+ err |= get_user(jmp, (unsigned short *)(regs->eip + 10)); >+ err |= get_user(ret, (unsigned long *)regs->esp); >+ >+ if (err) >+ break; >+ >+ err = get_user(call, (unsigned short *)(ret-2)); >+ if (err) >+ break; >+ >+ if ((mov1 & 0xF8) == 0xB8 && >+ (mov2 & 0xF8) == 0xB8 && >+ (mov1 & 0x07) != (mov2 & 0x07) && >+ (jmp & 0xF8FF) == 0xE0FF && >+ (mov2 & 0x07) == ((jmp>>8) & 0x07) && >+ (call & 0xF8FF) == 0xD0FF && >+ regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]]) >+ { >+ ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1; >+ ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2; >+ regs->eip = addr2; >+ return 4; >+ } >+ } while (0); >+ >+ do { /* PaX: gcc trampoline emulation #2 */ >+ unsigned char mov, jmp; >+ unsigned long addr1, addr2, ret; >+ unsigned short call; >+ >+ err = get_user(mov, (unsigned char *)regs->eip); >+ err |= get_user(addr1, (unsigned long *)(regs->eip + 1)); >+ err |= get_user(jmp, (unsigned char *)(regs->eip + 5)); >+ err |= get_user(addr2, (unsigned long *)(regs->eip + 6)); >+ err |= get_user(ret, (unsigned long *)regs->esp); >+ >+ if (err) >+ break; >+ >+ err = get_user(call, (unsigned short *)(ret-2)); >+ if (err) >+ break; >+ >+ if ((mov & 0xF8) == 0xB8 && >+ jmp == 0xE9 && >+ (call & 0xF8FF) == 0xD0FF && >+ regs->eip == ((unsigned long*)regs)[trans[(call>>8) & 0x07]]) >+ { >+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1; >+ regs->eip += addr2 + 10; >+ return 4; >+ } >+ } while (0); >+#endif >+ >+ return 1; /* PaX in action */ >+} >+ >+void pax_report_insns(void *pc) >+{ >+ unsigned long i; >+ >+ printk(KERN_ERR "PAX: bytes at PC: "); >+ for (i = 0; i < 20; i++) { >+ unsigned char c; >+ if (get_user(c, (unsigned char*)pc+i)) { >+ printk("<invalid address>."); >+ break; >+ } >+ printk("%02x ", c); >+ } >+ printk("\n"); >+} >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+/* >+ * PaX: handle the extra page faults or pass it down to the original handler >+ * >+ * returns 0 when nothing special was detected >+ * 1 when sigreturn trampoline (syscall) has to be emulated >+ */ >+asmlinkage int pax_do_page_fault(struct pt_regs *regs, unsigned long error_code) >+{ >+ struct mm_struct *mm = current->mm; >+ unsigned long address; >+ pte_t *pte; >+ unsigned char pte_mask; >+ int ret; >+ >+ __asm__("movl %%cr2,%0":"=r" (address)); >+ >+ /* It's safe to allow irq's after cr2 has been saved */ >+ if (likely(regs->eflags & X86_EFLAGS_IF)) >+ local_irq_enable(); >+ >+ if (unlikely((error_code & 5) != 5 || >+ address >= TASK_SIZE || >+ !(current->flags & PF_PAX_PAGEEXEC))) >+ return do_page_fault(regs, error_code, address); >+ >+ /* PaX: it's our fault, let's handle it if we can */ >+ >+ /* PaX: take a look at read faults before acquiring any locks */ >+ if (unlikely((error_code == 5) && (regs->eip == address))) { >+ /* instruction fetch attempt from a protected page in user mode */ >+ ret = pax_handle_fetch_fault(regs); >+ switch (ret) { >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ case 5: >+ return 0; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ case 4: >+ return 0; >+ case 3: >+ case 2: >+ return 1; >+#endif >+ case 1: >+ default: >+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp); >+ do_exit(SIGKILL); >+ } >+ } >+ >+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1)); >+ >+ spin_lock(&mm->page_table_lock); >+ pte = pax_get_pte(mm, address); >+ if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) { >+ spin_unlock(&mm->page_table_lock); >+ do_page_fault(regs, error_code, address); >+ return 0; > } >+ >+ if (unlikely((error_code == 7) && !pte_write(*pte))) { >+ /* write attempt to a protected page in user mode */ >+ spin_unlock(&mm->page_table_lock); >+ do_page_fault(regs, error_code, address); >+ return 0; >+ } >+ >+ /* >+ * PaX: fill DTLB with user rights and retry >+ */ >+ __asm__ __volatile__ ( >+ "orb %2,%1\n" >+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC) >+/* >+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's >+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any* >+ * page fault when examined during a TLB load attempt. this is true not only >+ * for PTEs holding a non-present entry but also present entries that will >+ * raise a page fault (such as those set up by PaX, or the copy-on-write >+ * mechanism). in effect it means that we do *not* need to flush the TLBs >+ * for our target pages since their PTEs are simply not in the TLBs at all. >+ * the best thing in omitting it is that we gain around 15-20% speed in the >+ * fast path of the page fault handler and can get rid of tracing since we >+ * can no longer flush unintended entries. >+ */ >+ >+ "invlpg %0\n" >+#endif >+ >+ "testb $0,%0\n" >+ "xorb %3,%1\n" >+ : >+ : "m" (*(char*)address), "m" (*(char*)pte) , "q" (pte_mask) , "i" (_PAGE_USER) >+ : "memory", "cc"); >+ spin_unlock(&mm->page_table_lock); >+ return 0; > } >+#endif >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/mm/init.c linux-2.4.22-ppc-dev/arch/i386/mm/init.c >--- linux-2.4.22-ppc-dev.orig/arch/i386/mm/init.c 2003-09-14 14:03:57.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/mm/init.c 2003-09-14 14:07:40.000000000 +0200 >@@ -37,6 +37,8 @@ > #include <asm/e820.h> > #include <asm/apic.h> > #include <asm/tlb.h> >+#include <asm/page_offset.h> >+#include <asm/desc.h> > > mmu_gather_t mmu_gathers[NR_CPUS]; > unsigned long highstart_pfn, highend_pfn; >@@ -122,7 +124,7 @@ > > /* References to section boundaries */ > >-extern char _text, _etext, _edata, __bss_start, _end; >+extern char _text, _etext, _data, _edata, __bss_start, _end; > extern char __init_begin, __init_end; > > static inline void set_pte_phys (unsigned long vaddr, >@@ -521,7 +523,7 @@ > reservedpages = free_pages_init(); > > codesize = (unsigned long) &_etext - (unsigned long) &_text; >- datasize = (unsigned long) &_edata - (unsigned long) &_etext; >+ datasize = (unsigned long) &_edata - (unsigned long) &_data; > initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; > > printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n", >@@ -589,6 +591,42 @@ > totalram_pages++; > } > printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ /* PaX: limit KERNEL_CS to actual size */ >+ { >+ unsigned long limit; >+ >+ limit = (unsigned long)&_etext >> PAGE_SHIFT; >+ gdt_table[2].a = (gdt_table[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL); >+ gdt_table[2].b = (gdt_table[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL); >+ >+ /* PaX: nuke __FLAT_KERNEL_CS, no longer needed */ >+ gdt_table[1].a = 0UL; >+ gdt_table[1].b = 0UL; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ gdt_table2[2].a = (gdt_table2[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL); >+ gdt_table2[2].b = (gdt_table2[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL); >+ >+ /* PaX: nuke __FLAT_KERNEL_CS, no longer needed */ >+ gdt_table2[1].a = 0UL; >+ gdt_table2[1].b = 0UL; >+#endif >+ >+ /* PaX: make KERNEL_CS read-only */ >+ for (addr = __KERNEL_TEXT_OFFSET; addr < __KERNEL_TEXT_OFFSET + 0x00400000UL; addr += (1UL << PMD_SHIFT)) { >+ pgd_t *pgd; >+ pmd_t *pmd; >+ >+ pgd = pgd_offset_k(addr); >+ pmd = pmd_offset(pgd, addr); >+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW)); >+ } >+ flush_tlb_all(); >+ } >+#endif >+ > } > > #ifdef CONFIG_BLK_DEV_INITRD >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/vmlinux.lds linux-2.4.22-ppc-dev/arch/i386/vmlinux.lds >--- linux-2.4.22-ppc-dev.orig/arch/i386/vmlinux.lds 2003-09-14 14:03:58.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/i386/vmlinux.lds 1970-01-01 01:00:00.000000000 +0100 >@@ -1,82 +0,0 @@ >-/* ld script to make i386 Linux kernel >- * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; >- */ >-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") >-OUTPUT_ARCH(i386) >-ENTRY(_start) >-SECTIONS >-{ >- . = 0xC0000000 + 0x100000; >- _text = .; /* Text and read-only data */ >- .text : { >- *(.text) >- *(.fixup) >- *(.gnu.warning) >- } = 0x9090 >- >- _etext = .; /* End of text section */ >- >- .rodata : { *(.rodata) *(.rodata.*) } >- .kstrtab : { *(.kstrtab) } >- >- . = ALIGN(16); /* Exception table */ >- __start___ex_table = .; >- __ex_table : { *(__ex_table) } >- __stop___ex_table = .; >- >- __start___ksymtab = .; /* Kernel symbol table */ >- __ksymtab : { *(__ksymtab) } >- __stop___ksymtab = .; >- >- .data : { /* Data */ >- *(.data) >- CONSTRUCTORS >- } >- >- _edata = .; /* End of data section */ >- >- . = ALIGN(8192); /* init_task */ >- .data.init_task : { *(.data.init_task) } >- >- . = ALIGN(4096); /* Init code and data */ >- __init_begin = .; >- .text.init : { *(.text.init) } >- .data.init : { *(.data.init) } >- . = ALIGN(16); >- __setup_start = .; >- .setup.init : { *(.setup.init) } >- __setup_end = .; >- __initcall_start = .; >- .initcall.init : { *(.initcall.init) } >- __initcall_end = .; >- . = ALIGN(4096); >- __init_end = .; >- >- . = ALIGN(4096); >- .data.page_aligned : { *(.data.idt) } >- >- . = ALIGN(32); >- .data.cacheline_aligned : { *(.data.cacheline_aligned) } >- >- __bss_start = .; /* BSS */ >- .bss : { >- *(.bss) >- } >- _end = . ; >- >- /* Sections to be discarded */ >- /DISCARD/ : { >- *(.text.exit) >- *(.data.exit) >- *(.exitcall.exit) >- } >- >- /* Stabs debugging sections. */ >- .stab 0 : { *(.stab) } >- .stabstr 0 : { *(.stabstr) } >- .stab.excl 0 : { *(.stab.excl) } >- .stab.exclstr 0 : { *(.stab.exclstr) } >- .stab.index 0 : { *(.stab.index) } >- .stab.indexstr 0 : { *(.stab.indexstr) } >- .comment 0 : { *(.comment) } >-} >diff -Naur linux-2.4.22-ppc-dev.orig/arch/i386/vmlinux.lds.S linux-2.4.22-ppc-dev/arch/i386/vmlinux.lds.S >--- linux-2.4.22-ppc-dev.orig/arch/i386/vmlinux.lds.S 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/arch/i386/vmlinux.lds.S 2003-09-14 14:07:40.000000000 +0200 >@@ -0,0 +1,136 @@ >+/* ld script to make i386 Linux kernel >+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>; >+ */ >+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") >+OUTPUT_ARCH(i386) >+ENTRY(_start) >+SECTIONS >+{ >+ . = __PAGE_OFFSET + 0x100000; >+ .text.startup : { >+ BYTE(0xEA) /* jmp far */ >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET) >+#else >+ LONG(startup_32 - __PAGE_OFFSET) >+#endif >+ >+ SHORT(__KERNEL_CS) >+ } >+ >+ . = ALIGN(32); >+ _data = .; >+ .data : { /* Data */ >+ *(.data) >+ CONSTRUCTORS >+ } >+ >+ . = ALIGN(32); >+ .data.cacheline_aligned : { *(.data.cacheline_aligned) } >+ >+ . = ALIGN(8192); >+ .data.init_task : { *(.data.init_task) } >+ >+ . = ALIGN(4096); >+ .data.page_aligned : { *(.data.swapper_pg_dir) } >+ >+ _edata = .; /* End of data section */ >+ >+ __bss_start = .; /* BSS */ >+ .bss : { >+ *(.bss) >+ LONG(0) >+ } >+ __bss_end = . ; >+ >+ . = ALIGN(4096); /* Init code and data */ >+ __init_begin = .; >+ >+ .data.init : { >+ *(.data.pg0) >+ *(.data.pg1) >+ *(.data.pg2) >+ *(.data.init) >+ } >+ . = ALIGN(16); >+ __setup_start = .; >+ .setup.init : { *(.setup.init) } >+ __setup_end = .; >+ __initcall_start = .; >+ .initcall.init : { *(.initcall.init) } >+ __initcall_end = .; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ __text_init_start = .; >+ .text.init (. - __KERNEL_TEXT_OFFSET) : AT (__text_init_start) { >+ *(.text.init) >+ . = ALIGN(4*1024*1024) - 1; >+ BYTE(0) >+ } >+ __init_end = . + __KERNEL_TEXT_OFFSET; >+ >+/* >+ * PaX: this must be kept in synch with the KERNEL_CS base >+ * in the GDTs in arch/i386/kernel/head.S >+ */ >+ _text = .; /* Text and read-only data */ >+ .text : AT (. + __KERNEL_TEXT_OFFSET) { >+#else >+ .text.init : { *(.text.init) } >+ . = ALIGN(4096); >+ __init_end = .; >+ _text = .; /* Text and read-only data */ >+ .text : { >+#endif >+ >+ *(.text) >+ *(.fixup) >+ *(.gnu.warning) >+ } = 0x9090 >+ >+ _etext = .; /* End of text section */ >+ . = ALIGN(4096); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ . += __KERNEL_TEXT_OFFSET; >+#endif >+ >+ .rodata.page_aligned : { >+ *(.data.empty_zero_page) >+ *(.data.idt) >+ } >+ .rodata : { *(.rodata) *(.rodata.*) } >+ .kstrtab : { *(.kstrtab) } >+ >+ . = ALIGN(16); /* Exception table */ >+ __start___ex_table = .; >+ __ex_table : { *(__ex_table) } >+ __stop___ex_table = .; >+ >+ __start___ksymtab = .; /* Kernel symbol table */ >+ __ksymtab : { *(__ksymtab) } >+ __stop___ksymtab = .; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_KERNEXEC >+ _end = ALIGN(4*1024*1024); >+#else >+ _end = .; >+#endif >+ >+ /* Sections to be discarded */ >+ /DISCARD/ : { >+ *(.text.exit) >+ *(.data.exit) >+ *(.exitcall.exit) >+ } >+ >+ /* Stabs debugging sections. */ >+ .stab 0 : { *(.stab) } >+ .stabstr 0 : { *(.stabstr) } >+ .stab.excl 0 : { *(.stab.excl) } >+ .stab.exclstr 0 : { *(.stab.exclstr) } >+ .stab.index 0 : { *(.stab.index) } >+ .stab.indexstr 0 : { *(.stab.indexstr) } >+ .comment 0 : { *(.comment) } >+} >diff -Naur linux-2.4.22-ppc-dev.orig/arch/ia64/config.in linux-2.4.22-ppc-dev/arch/ia64/config.in >--- linux-2.4.22-ppc-dev.orig/arch/ia64/config.in 2003-09-14 14:04:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/ia64/config.in 2003-09-14 14:07:40.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 -Naur linux-2.4.22-ppc-dev.orig/arch/ia64/kernel/ptrace.c linux-2.4.22-ppc-dev/arch/ia64/kernel/ptrace.c >--- linux-2.4.22-ppc-dev.orig/arch/ia64/kernel/ptrace.c 2003-09-14 14:04:13.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/ia64/kernel/ptrace.c 2003-09-14 14:07:40.000000000 +0200 >@@ -16,6 +16,7 @@ > #include <linux/ptrace.h> > #include <linux/smp_lock.h> > #include <linux/user.h> >+#include <linux/grsecurity.h> > > #include <asm/pgtable.h> > #include <asm/processor.h> >@@ -1213,6 +1214,9 @@ > if (pid == 1) /* no messing around with init! */ > goto out_tsk; > >+ if (gr_handle_ptrace(child, request)) >+ goto out_tsk; >+ > if (request == PTRACE_ATTACH) { > ret = ptrace_attach(child); > goto out_tsk; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/ia64/kernel/sys_ia64.c linux-2.4.22-ppc-dev/arch/ia64/kernel/sys_ia64.c >--- linux-2.4.22-ppc-dev.orig/arch/ia64/kernel/sys_ia64.c 2003-09-14 14:04:13.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/ia64/kernel/sys_ia64.c 2003-09-14 14:07:40.000000000 +0200 >@@ -15,6 +15,7 @@ > #include <linux/smp.h> > #include <linux/smp_lock.h> > #include <linux/highuid.h> >+#include <linux/grsecurity.h> > > #include <asm/shmparam.h> > #include <asm/uaccess.h> >@@ -206,6 +207,11 @@ > goto out; > } > >+ if (gr_handle_mmap(file, prot)) { >+ addr = -EACCES; >+ goto out; >+ } >+ > down_write(¤t->mm->mmap_sem); > addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); > up_write(¤t->mm->mmap_sem); >diff -Naur linux-2.4.22-ppc-dev.orig/arch/m68k/config.in linux-2.4.22-ppc-dev/arch/m68k/config.in >--- linux-2.4.22-ppc-dev.orig/arch/m68k/config.in 2003-09-14 14:04:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/m68k/config.in 2003-09-14 14:07:40.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 -Naur linux-2.4.22-ppc-dev.orig/arch/mips/config.in linux-2.4.22-ppc-dev/arch/mips/config.in >--- linux-2.4.22-ppc-dev.orig/arch/mips/config.in 2003-09-14 14:04:01.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/mips/config.in 2003-09-14 14:07:40.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 -Naur linux-2.4.22-ppc-dev.orig/arch/mips64/config.in linux-2.4.22-ppc-dev/arch/mips64/config.in >--- linux-2.4.22-ppc-dev.orig/arch/mips64/config.in 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/mips64/config.in 2003-09-14 14:07:40.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 -Naur linux-2.4.22-ppc-dev.orig/arch/parisc/config.in linux-2.4.22-ppc-dev/arch/parisc/config.in >--- linux-2.4.22-ppc-dev.orig/arch/parisc/config.in 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/parisc/config.in 2003-09-14 14:07:40.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 -Naur linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/ioctl32.c linux-2.4.22-ppc-dev/arch/parisc/kernel/ioctl32.c >--- linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/ioctl32.c 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/parisc/kernel/ioctl32.c 2003-09-14 14:07:40.000000000 +0200 >@@ -1434,7 +1434,11 @@ > * To have permissions to do most of the vt ioctls, we either have > * to be the owner of the tty, or super-user. > */ >+#ifdef CONFIG_GRKERNSEC >+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) >+#else > if (current->tty == tty || suser()) >+#endif > return 1; > return 0; > } >diff -Naur linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/ptrace.c linux-2.4.22-ppc-dev/arch/parisc/kernel/ptrace.c >--- linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/ptrace.c 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/parisc/kernel/ptrace.c 2003-09-14 14:07:40.000000000 +0200 >@@ -15,7 +15,7 @@ > #include <linux/ptrace.h> > #include <linux/user.h> > #include <linux/personality.h> >- >+#include <linux/grsecurity.h> > #include <asm/uaccess.h> > #include <asm/pgtable.h> > #include <asm/system.h> >@@ -119,6 +119,9 @@ > if (pid == 1) /* no messing around with init! */ > goto out_tsk; > >+ if (gr_handle_ptrace(child, request)) >+ goto out_tsk; >+ > if (request == PTRACE_ATTACH) { > ret = ptrace_attach(child); > goto out_tsk; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/sys_parisc.c linux-2.4.22-ppc-dev/arch/parisc/kernel/sys_parisc.c >--- linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/sys_parisc.c 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/parisc/kernel/sys_parisc.c 2003-09-14 14:07:40.000000000 +0200 >@@ -12,6 +12,7 @@ > #include <linux/mman.h> > #include <linux/shm.h> > #include <linux/smp_lock.h> >+#include <linux/grsecurity.h> > > int sys_pipe(int *fildes) > { >@@ -90,6 +91,11 @@ > inode = filp->f_dentry->d_inode; > } > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp)) >+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; >+#endif >+ > if (inode && (flags & MAP_SHARED) && (inode->i_mapping->i_mmap_shared)) { > addr = get_shared_area(inode, addr, len, pgoff); > } else { >@@ -104,12 +110,23 @@ > { > struct file * file = NULL; > unsigned long error = -EBADF; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > if (!(flags & MAP_ANONYMOUS)) { > file = fget(fd); > if (!file) > goto out; > } > >+ if (gr_handle_mmap(file, prot)) { >+ fput(file); >+ return -EACCES; >+ } >+ > flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); > > down_write(¤t->mm->mmap_sem); >diff -Naur linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/sys_parisc32.c linux-2.4.22-ppc-dev/arch/parisc/kernel/sys_parisc32.c >--- linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/sys_parisc32.c 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/parisc/kernel/sys_parisc32.c 2003-09-14 14:07:40.000000000 +0200 >@@ -50,6 +50,7 @@ > #include <linux/highmem.h> > #include <linux/highuid.h> > #include <linux/mman.h> >+#include <linux/grsecurity.h> > > #include <asm/types.h> > #include <asm/uaccess.h> >@@ -177,6 +178,11 @@ > struct file *file; > int retval; > int i; >+#ifdef CONFIG_GRKERNSEC >+ struct file *old_exec_file; >+ struct acl_subject_label *old_acl; >+ struct rlimit old_rlim[RLIM_NLIMITS]; >+#endif > > file = open_exec(filename); > >@@ -184,7 +190,26 @@ > if (IS_ERR(file)) > return retval; > >+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes)); >+ >+ if (gr_handle_nproc()) { >+ allow_write_access(file); >+ fput(file); >+ return -EAGAIN; >+ } >+ >+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) { >+ allow_write_access(file); >+ fput(file); >+ return -EACCES; >+ } >+ > bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK >+ bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK; >+#endif >+ > memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); > > DBG(("do_execve32(%s, %p, %p, %p)\n", filename, argv, envp, regs)); >@@ -209,11 +234,24 @@ > if (retval < 0) > goto out; > >+ if (!gr_tpe_allow(file)) { >+ retval = -EACCES; >+ goto out; >+ } >+ >+ if (gr_check_crash_exec(file)) { >+ retval = -EACCES; >+ goto out; >+ } >+ > retval = copy_strings_kernel(1, &bprm.filename, &bprm); > if (retval < 0) > goto out; > > bprm.exec = bprm.p; >+ >+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); >+ > retval = copy_strings32(bprm.envc, envp, &bprm); > if (retval < 0) > goto out; >@@ -222,11 +260,32 @@ > if (retval < 0) > goto out; > >+#ifdef CONFIG_GRKERNSEC >+ old_acl = current->acl; >+ memcpy(old_rlim, current->rlim, sizeof(old_rlim)); >+ old_exec_file = current->exec_file; >+ get_file(file); >+ current->exec_file = file; >+#endif >+ >+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt); >+ > 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 >+ current->acl = old_acl; >+ memcpy(current->rlim, old_rlim, sizeof(old_rlim)); >+ 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 -Naur linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/traps.c linux-2.4.22-ppc-dev/arch/parisc/kernel/traps.c >--- linux-2.4.22-ppc-dev.orig/arch/parisc/kernel/traps.c 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/parisc/kernel/traps.c 2003-09-14 14:07:41.000000000 +0200 >@@ -637,9 +637,7 @@ > > down_read(¤t->mm->mmap_sem); > vma = find_vma(current->mm,regs->iaoq[0]); >- if (vma && (regs->iaoq[0] >= vma->vm_start) >- && (vma->vm_flags & VM_EXEC)) { >- >+ if (vma && (regs->iaoq[0] >= vma->vm_start)) { > fault_address = regs->iaoq[0]; > fault_space = regs->iasq[0]; > >diff -Naur linux-2.4.22-ppc-dev.orig/arch/parisc/mm/fault.c linux-2.4.22-ppc-dev/arch/parisc/mm/fault.c >--- linux-2.4.22-ppc-dev.orig/arch/parisc/mm/fault.c 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/parisc/mm/fault.c 2003-09-14 14:07:41.000000000 +0200 >@@ -15,6 +15,7 @@ > #include <linux/ptrace.h> > #include <linux/sched.h> > #include <linux/interrupt.h> >+#include <linux/unistd.h> > > #include <asm/uaccess.h> > #include <asm/traps.h> >@@ -53,7 +54,7 @@ > static unsigned long > parisc_acctyp(unsigned long code, unsigned int inst) > { >- if (code == 6 || code == 16) >+ if (code == 6 || code == 7 || code == 16) > return VM_EXEC; > > switch (inst & 0xf0000000) { >@@ -139,6 +140,136 @@ > } > #endif > >+/* >+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address) >+ * >+ * returns 1 when task should be killed >+ * 2 when rt_sigreturn trampoline was detected >+ * 3 when unpatched PLT trampoline was detected >+ * 4 when legitimate ET_EXEC was detected >+ */ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+static int pax_handle_fetch_fault(struct pt_regs *regs) >+{ >+ int err; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (current->flags & PF_PAX_RANDEXEC) { >+ if (instruction_pointer(regs) >= current->mm->start_code && >+ instruction_pointer(regs) < current->mm->end_code) >+ { >+#if 0 >+ /* PaX: this needs fixing */ >+ if ((regs->gr[2] & ~3UL) == instruction_pointer(regs)) >+ return 1; >+#endif >+ regs->iaoq[0] += current->mm->delta_exec; >+ if ((regs->iaoq[1] & ~3UL) >= current->mm->start_code && >+ (regs->iaoq[1] & ~3UL) < current->mm->end_code) >+ regs->iaoq[1] += current->mm->delta_exec; >+ return 4; >+ } >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ do { /* PaX: unpatched PLT emulation */ >+ unsigned int bl, depwi; >+ >+ err = get_user(bl, (unsigned int*)instruction_pointer(regs)); >+ err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4)); >+ >+ if (err) >+ break; >+ >+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) { >+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12; >+ >+ err = get_user(ldw, (unsigned int*)addr); >+ err |= get_user(bv, (unsigned int*)(addr+4)); >+ err |= get_user(ldw2, (unsigned int*)(addr+8)); >+ >+ if (err) >+ break; >+ >+ if (ldw == 0x0E801096U && >+ bv == 0xEAC0C000U && >+ ldw2 == 0x0E881095U) >+ { >+ unsigned int resolver, map; >+ >+ err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8)); >+ err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12)); >+ if (err) >+ break; >+ >+ regs->gr[20] = instruction_pointer(regs)+8; >+ regs->gr[21] = map; >+ regs->gr[22] = resolver; >+ regs->iaoq[0] = resolver | 3UL; >+ regs->iaoq[1] = regs->iaoq[0] + 4; >+ return 3; >+ } >+ } >+ } while (0); >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ >+#ifndef CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ if (!(current->flags & PF_PAX_EMUTRAMP)) >+ return 1; >+#endif >+ >+ do { /* PaX: rt_sigreturn emulation */ >+ unsigned int ldi1, ldi2, bel, nop; >+ >+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs)); >+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4)); >+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8)); >+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12)); >+ >+ if (err) >+ break; >+ >+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) && >+ ldi2 == 0x3414015AU && >+ bel == 0xE4008200U && >+ nop == 0x08000240U) >+ { >+ regs->gr[25] = (ldi1 & 2) >> 1; >+ regs->gr[20] = __NR_rt_sigreturn; >+ regs->gr[31] = regs->iaoq[1] + 16; >+ regs->sr[0] = regs->iasq[1]; >+ regs->iaoq[0] = 0x100UL; >+ regs->iaoq[1] = regs->iaoq[0] + 4; >+ regs->iasq[0] = regs->sr[2]; >+ regs->iasq[1] = regs->sr[2]; >+ return 2; >+ } >+ } while (0); >+#endif >+ >+ return 1; >+} >+ >+void pax_report_insns(void *pc) >+{ >+ unsigned long i; >+ >+ printk(KERN_ERR "PAX: bytes at PC: "); >+ for (i = 0; i < 5; i++) { >+ unsigned int c; >+ if (get_user(c, (unsigned int*)pc+i)) { >+ printk("<invalid address>."); >+ break; >+ } >+ printk("%08x ", c); >+ } >+ printk("\n"); >+} >+#endif >+ > void do_page_fault(struct pt_regs *regs, unsigned long code, > unsigned long address) > { >@@ -164,8 +295,38 @@ > > acc_type = parisc_acctyp(code,regs->iir); > >- if ((vma->vm_flags & acc_type) != acc_type) >+ if ((vma->vm_flags & acc_type) != acc_type) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if ((current->flags & PF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) && >+ (address & ~3UL) == instruction_pointer(regs)) >+ { >+ up_read(&mm->mmap_sem); >+ switch(pax_handle_fetch_fault(regs)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ case 4: >+ return; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ case 3: >+ return; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ case 2: >+ return; >+#endif >+ >+ } >+ pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]); >+ do_exit(SIGKILL); >+ } >+#endif >+ > goto bad_area; >+ } > > /* > * If for any reason at all we couldn't handle the fault, make >diff -Naur linux-2.4.22-ppc-dev.orig/arch/ppc/config.in linux-2.4.22-ppc-dev/arch/ppc/config.in >--- linux-2.4.22-ppc-dev.orig/arch/ppc/config.in 2003-09-14 14:06:51.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/ppc/config.in 2003-09-14 14:07:41.000000000 +0200 >@@ -499,3 +499,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 -Naur linux-2.4.22-ppc-dev.orig/arch/ppc/kernel/ptrace.c linux-2.4.22-ppc-dev/arch/ppc/kernel/ptrace.c >--- linux-2.4.22-ppc-dev.orig/arch/ppc/kernel/ptrace.c 2003-09-14 14:04:05.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/ppc/kernel/ptrace.c 2003-09-14 14:07:41.000000000 +0200 >@@ -24,6 +24,7 @@ > #include <linux/errno.h> > #include <linux/ptrace.h> > #include <linux/user.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/page.h> >@@ -195,6 +196,9 @@ > if (pid == 1) /* you may not mess with init */ > goto out_tsk; > >+ if (gr_handle_ptrace(child, request)) >+ goto out_tsk; >+ > if (request == PTRACE_ATTACH) { > ret = ptrace_attach(child); > goto out_tsk; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/ppc/kernel/syscalls.c linux-2.4.22-ppc-dev/arch/ppc/kernel/syscalls.c >--- linux-2.4.22-ppc-dev.orig/arch/ppc/kernel/syscalls.c 2003-09-14 14:04:05.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/ppc/kernel/syscalls.c 2003-09-14 14:07:41.000000000 +0200 >@@ -35,6 +35,7 @@ > #include <linux/ipc.h> > #include <linux/utsname.h> > #include <linux/file.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/ipc.h> >@@ -175,14 +176,25 @@ > struct file * file = NULL; > int ret = -EBADF; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); > if (!(flags & MAP_ANONYMOUS)) { > if (!(file = fget(fd))) > goto out; > } > >+ if (gr_handle_mmap(file, prot)) { >+ fput(file); >+ ret = -EACCES; >+ goto out; >+ } >+ > down_write(¤t->mm->mmap_sem); >- ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); >+ ret = do_mmap(file, addr, len, prot, flags, pgoff << PAGE_SHIFT); > up_write(¤t->mm->mmap_sem); > if (file) > fput(file); >diff -Naur linux-2.4.22-ppc-dev.orig/arch/ppc/mm/fault.c linux-2.4.22-ppc-dev/arch/ppc/mm/fault.c >--- linux-2.4.22-ppc-dev.orig/arch/ppc/mm/fault.c 2003-09-14 14:06:52.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/ppc/mm/fault.c 2003-09-14 14:07:41.000000000 +0200 >@@ -26,6 +26,9 @@ > #include <linux/mman.h> > #include <linux/mm.h> > #include <linux/interrupt.h> >+#include <linux/slab.h> >+#include <linux/pagemap.h> >+#include <linux/compiler.h> > > #include <asm/page.h> > #include <asm/pgtable.h> >@@ -52,6 +55,360 @@ > void bad_page_fault(struct pt_regs *, unsigned long, int sig); > void do_page_fault(struct pt_regs *, unsigned long, unsigned long); > >+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT >+void pax_syscall_close(struct vm_area_struct * vma) >+{ >+ vma->vm_mm->call_syscall = 0UL; >+} >+ >+static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) >+{ >+ struct page* page; >+ unsigned int *kaddr; >+ >+ page = alloc_page(GFP_HIGHUSER); >+ if (!page) >+ return page; >+ >+ kaddr = kmap(page); >+ memset(kaddr, 0, PAGE_SIZE); >+ kaddr[0] = 0x44000002U; /* sc */ >+ __flush_dcache_icache(kaddr); >+ kunmap(page); >+ return page; >+} >+ >+static struct vm_operations_struct pax_vm_ops = { >+ close: pax_syscall_close, >+ nopage: pax_syscall_nopage, >+}; >+ >+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) >+{ >+ vma->vm_mm = current->mm; >+ vma->vm_start = addr; >+ vma->vm_end = addr + PAGE_SIZE; >+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; >+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; >+ vma->vm_ops = &pax_vm_ops; >+ vma->vm_pgoff = 0UL; >+ vma->vm_file = NULL; >+ vma->vm_private_data = NULL; >+ insert_vm_struct(current->mm, vma); >+ ++current->mm->total_vm; >+} >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+/* >+ * PaX: decide what to do with offenders (regs->nip = fault address) >+ * >+ * returns 1 when task should be killed >+ * 2 when patched GOT trampoline was detected >+ * 3 when patched PLT trampoline was detected >+ * 4 when unpatched PLT trampoline was detected >+ * 5 when legitimate ET_EXEC was detected >+ * 6 when sigreturn trampoline was detected >+ * 7 when rt_sigreturn trampoline was detected >+ */ >+static int pax_handle_fetch_fault(struct pt_regs *regs) >+{ >+ int err; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (current->flags & PF_PAX_RANDEXEC) { >+ if (regs->nip >= current->mm->start_code && >+ regs->nip < current->mm->end_code) >+ { >+ if (regs->link == regs->nip) >+ return 1; >+ >+ regs->nip += current->mm->delta_exec; >+ return 5; >+ } >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ do { /* PaX: patched GOT emulation */ >+ unsigned int blrl; >+ >+ err = get_user(blrl, (unsigned int*)regs->nip); >+ >+ if (!err && blrl == 0x4E800021U) { >+ unsigned long temp = regs->nip; >+ >+ regs->nip = regs->link & 0xFFFFFFFCUL; >+ regs->link = temp + 4UL; >+ return 2; >+ } >+ } while (0); >+ >+ do { /* PaX: patched PLT emulation #1 */ >+ unsigned int b; >+ >+ err = get_user(b, (unsigned int *)regs->nip); >+ >+ if (!err && (b & 0xFC000003U) == 0x48000000U) { >+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL); >+ return 3; >+ } >+ } while (0); >+ >+ do { /* PaX: unpatched PLT emulation #1 */ >+ unsigned int li, b; >+ >+ err = get_user(li, (unsigned int *)regs->nip); >+ err |= get_user(b, (unsigned int *)(regs->nip+4)); >+ >+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { >+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; >+ unsigned long addr = b | 0xFC000000UL; >+ >+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); >+ err = get_user(rlwinm, (unsigned int*)addr); >+ err |= get_user(add, (unsigned int*)(addr+4)); >+ err |= get_user(li2, (unsigned int*)(addr+8)); >+ err |= get_user(addis2, (unsigned int*)(addr+12)); >+ err |= get_user(mtctr, (unsigned int*)(addr+16)); >+ err |= get_user(li3, (unsigned int*)(addr+20)); >+ err |= get_user(addis3, (unsigned int*)(addr+24)); >+ err |= get_user(bctr, (unsigned int*)(addr+28)); >+ >+ if (err) >+ break; >+ >+ if (rlwinm == 0x556C083CU && >+ add == 0x7D6C5A14U && >+ (li2 & 0xFFFF0000U) == 0x39800000U && >+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && >+ mtctr == 0x7D8903A6U && >+ (li3 & 0xFFFF0000U) == 0x39800000U && >+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && >+ bctr == 0x4E800420U) >+ { >+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); >+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); >+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; >+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); >+ regs->ctr += (addis2 & 0xFFFFU) << 16; >+ regs->nip = regs->ctr; >+ return 4; >+ } >+ } >+ } while (0); >+ >+#if 0 >+ do { /* PaX: unpatched PLT emulation #2 */ >+ unsigned int lis, lwzu, b, bctr; >+ >+ err = get_user(lis, (unsigned int *)regs->nip); >+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4)); >+ err |= get_user(b, (unsigned int *)(regs->nip+8)); >+ err |= get_user(bctr, (unsigned int *)(regs->nip+12)); >+ >+ if (err) >+ break; >+ >+ if ((lis & 0xFFFF0000U) == 0x39600000U && >+ (lwzu & 0xU) == 0xU && >+ (b & 0xFC000003U) == 0x48000000U && >+ bctr == 0x4E800420U) >+ { >+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; >+ unsigned long addr = b | 0xFC000000UL; >+ >+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL); >+ err = get_user(addis, (unsigned int*)addr); >+ err |= get_user(addi, (unsigned int*)(addr+4)); >+ err |= get_user(rlwinm, (unsigned int*)(addr+8)); >+ err |= get_user(add, (unsigned int*)(addr+12)); >+ err |= get_user(li2, (unsigned int*)(addr+16)); >+ err |= get_user(addis2, (unsigned int*)(addr+20)); >+ err |= get_user(mtctr, (unsigned int*)(addr+24)); >+ err |= get_user(li3, (unsigned int*)(addr+28)); >+ err |= get_user(addis3, (unsigned int*)(addr+32)); >+ err |= get_user(bctr, (unsigned int*)(addr+36)); >+ >+ if (err) >+ break; >+ >+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && >+ (addi & 0xFFFF0000U) == 0x396B0000U && >+ rlwinm == 0x556C083CU && >+ add == 0x7D6C5A14U && >+ (li2 & 0xFFFF0000U) == 0x39800000U && >+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U && >+ mtctr == 0x7D8903A6U && >+ (li3 & 0xFFFF0000U) == 0x39800000U && >+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U && >+ bctr == 0x4E800420U) >+ { >+ regs->gpr[PT_R11] = >+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); >+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); >+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; >+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); >+ regs->ctr += (addis2 & 0xFFFFU) << 16; >+ regs->nip = regs->ctr; >+ return 4; >+ } >+ } >+ } while (0); >+#endif >+ >+ do { /* PaX: unpatched PLT emulation #3 */ >+ unsigned int li, b; >+ >+ err = get_user(li, (unsigned int *)regs->nip); >+ err |= get_user(b, (unsigned int *)(regs->nip+4)); >+ >+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { >+ unsigned int addis, lwz, mtctr, bctr; >+ unsigned long addr = b | 0xFC000000UL; >+ >+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); >+ err = get_user(addis, (unsigned int*)addr); >+ err |= get_user(lwz, (unsigned int*)(addr+4)); >+ err |= get_user(mtctr, (unsigned int*)(addr+8)); >+ err |= get_user(bctr, (unsigned int*)(addr+12)); >+ >+ if (err) >+ break; >+ >+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U && >+ (lwz & 0xFFFF0000U) == 0x816B0000U && >+ mtctr == 0x7D6903A6U && >+ bctr == 0x4E800420U) >+ { >+ unsigned int r11; >+ >+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); >+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); >+ >+ err = get_user(r11, (unsigned int*)addr); >+ if (err) >+ break; >+ >+ regs->gpr[PT_R11] = r11; >+ regs->ctr = r11; >+ regs->nip = r11; >+ return 4; >+ } >+ } >+ } while (0); >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ do { /* PaX: sigreturn emulation */ >+ unsigned int li, sc; >+ >+ err = get_user(li, (unsigned int *)regs->nip); >+ err |= get_user(sc, (unsigned int *)(regs->nip+4)); >+ >+ if (!err && li == 0x38007777U && sc == 0x44000002U) { >+ struct vm_area_struct *vma; >+ unsigned long call_syscall; >+ >+ down_read(¤t->mm->mmap_sem); >+ call_syscall = current->mm->call_syscall; >+ up_read(¤t->mm->mmap_sem); >+ if (likely(call_syscall)) >+ goto emulate; >+ >+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); >+ >+ down_write(¤t->mm->mmap_sem); >+ if (current->mm->call_syscall) { >+ call_syscall = current->mm->call_syscall; >+ up_write(¤t->mm->mmap_sem); >+ if (vma) kmem_cache_free(vm_area_cachep, vma); >+ goto emulate; >+ } >+ >+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); >+ if (!vma || (call_syscall & ~PAGE_MASK)) { >+ up_write(¤t->mm->mmap_sem); >+ if (vma) kmem_cache_free(vm_area_cachep, vma); >+ return 1; >+ } >+ >+ pax_insert_vma(vma, call_syscall); >+ current->mm->call_syscall = call_syscall; >+ up_write(¤t->mm->mmap_sem); >+ >+emulate: >+ regs->gpr[PT_R0] = 0x7777UL; >+ regs->nip = call_syscall; >+ return 6; >+ } >+ } while (0); >+ >+ do { /* PaX: rt_sigreturn emulation */ >+ unsigned int li, sc; >+ >+ err = get_user(li, (unsigned int *)regs->nip); >+ err |= get_user(sc, (unsigned int *)(regs->nip+4)); >+ >+ if (!err && li == 0x38006666U && sc == 0x44000002U) { >+ struct vm_area_struct *vma; >+ unsigned int call_syscall; >+ >+ down_read(¤t->mm->mmap_sem); >+ call_syscall = current->mm->call_syscall; >+ up_read(¤t->mm->mmap_sem); >+ if (likely(call_syscall)) >+ goto rt_emulate; >+ >+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); >+ >+ down_write(¤t->mm->mmap_sem); >+ if (current->mm->call_syscall) { >+ call_syscall = current->mm->call_syscall; >+ up_write(¤t->mm->mmap_sem); >+ if (vma) kmem_cache_free(vm_area_cachep, vma); >+ goto rt_emulate; >+ } >+ >+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); >+ if (!vma || (call_syscall & ~PAGE_MASK)) { >+ up_write(¤t->mm->mmap_sem); >+ if (vma) kmem_cache_free(vm_area_cachep, vma); >+ return 1; >+ } >+ >+ pax_insert_vma(vma, call_syscall); >+ current->mm->call_syscall = call_syscall; >+ up_write(¤t->mm->mmap_sem); >+ >+rt_emulate: >+ regs->gpr[PT_R0] = 0x6666UL; >+ regs->nip = call_syscall; >+ return 7; >+ } >+ } while (0); >+#endif >+ >+ return 1; >+} >+ >+void pax_report_insns(void *pc) >+{ >+ unsigned long i; >+ >+ printk(KERN_ERR "PAX: bytes at PC: "); >+ for (i = 0; i < 5; i++) { >+ unsigned int c; >+ if (get_user(c, (unsigned int*)pc+i)) { >+ printk("<invalid address>."); >+ break; >+ } >+ printk("%08x ", c); >+ } >+ printk("\n"); >+} >+#endif >+ > /* > * Check whether the instruction at regs->nip is a store using > * an update addressing form which will update r1. >@@ -112,7 +469,7 @@ > * indicate errors in DSISR but can validly be set in SRR1. > */ > if (regs->trap == 0x400) >- error_code &= 0x48200000; >+ error_code &= 0x58200000; > else > is_write = error_code & 0x02000000; > #endif /* CONFIG_4xx */ >@@ -246,6 +603,38 @@ > > /* User mode accesses cause a SIGSEGV */ > if (user_mode(regs)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (current->flags & PF_PAX_PAGEEXEC) { >+ if ((regs->trap == 0x400) && (regs->nip == address)) { >+ switch (pax_handle_fetch_fault(regs)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ case 2: >+ case 3: >+ case 4: >+ return; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ case 5: >+ return; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ case 6: >+ case 7: >+ return; >+#endif >+ >+ } >+ >+ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]); >+ do_exit(SIGKILL); >+ } >+ } >+#endif >+ > info.si_signo = SIGSEGV; > info.si_errno = 0; > info.si_code = code; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/ppc64/kernel/ioctl32.c linux-2.4.22-ppc-dev/arch/ppc64/kernel/ioctl32.c >--- linux-2.4.22-ppc-dev.orig/arch/ppc64/kernel/ioctl32.c 2003-09-14 14:03:57.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/ppc64/kernel/ioctl32.c 2003-09-14 14:07:41.000000000 +0200 >@@ -1800,7 +1800,11 @@ > * To have permissions to do most of the vt ioctls, we either have > * to be the owner of the tty, or super-user. > */ >+#ifdef CONFIG_GRKERNSEC >+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) >+#else > if (current->tty == tty || suser()) >+#endif > return 1; > return 0; > } >diff -Naur linux-2.4.22-ppc-dev.orig/arch/s390/config.in linux-2.4.22-ppc-dev/arch/s390/config.in >--- linux-2.4.22-ppc-dev.orig/arch/s390/config.in 2003-09-14 14:04:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/s390/config.in 2003-09-14 14:07:41.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 -Naur linux-2.4.22-ppc-dev.orig/arch/s390x/config.in linux-2.4.22-ppc-dev/arch/s390x/config.in >--- linux-2.4.22-ppc-dev.orig/arch/s390x/config.in 2003-09-14 14:04:17.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/s390x/config.in 2003-09-14 14:07:41.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 -Naur linux-2.4.22-ppc-dev.orig/arch/sh/config.in linux-2.4.22-ppc-dev/arch/sh/config.in >--- linux-2.4.22-ppc-dev.orig/arch/sh/config.in 2003-09-14 14:04:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sh/config.in 2003-09-14 14:07:41.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 -Naur linux-2.4.22-ppc-dev.orig/arch/sparc/boot/Makefile linux-2.4.22-ppc-dev/arch/sparc/boot/Makefile >--- linux-2.4.22-ppc-dev.orig/arch/sparc/boot/Makefile 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc/boot/Makefile 2003-09-14 14:07:41.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 -Naur linux-2.4.22-ppc-dev.orig/arch/sparc/config.in linux-2.4.22-ppc-dev/arch/sparc/config.in >--- linux-2.4.22-ppc-dev.orig/arch/sparc/config.in 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc/config.in 2003-09-14 14:07:41.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 -Naur linux-2.4.22-ppc-dev.orig/arch/sparc/kernel/ptrace.c linux-2.4.22-ppc-dev/arch/sparc/kernel/ptrace.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc/kernel/ptrace.c 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc/kernel/ptrace.c 2003-09-14 14:07:41.000000000 +0200 >@@ -17,6 +17,7 @@ > #include <linux/user.h> > #include <linux/smp.h> > #include <linux/smp_lock.h> >+#include <linux/grsecurity.h> > > #include <asm/pgtable.h> > #include <asm/system.h> >@@ -310,6 +311,9 @@ > goto out; > } > >+ if(gr_handle_ptrace(child, request)) >+ goto out_tsk; >+ > if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) > || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { > if (ptrace_attach(child)) { >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc/kernel/sys_sparc.c linux-2.4.22-ppc-dev/arch/sparc/kernel/sys_sparc.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc/kernel/sys_sparc.c 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc/kernel/sys_sparc.c 2003-09-14 14:07:41.000000000 +0200 >@@ -20,6 +20,7 @@ > #include <linux/utsname.h> > #include <linux/smp.h> > #include <linux/smp_lock.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/ipc.h> >@@ -54,6 +55,13 @@ > return -ENOMEM; > if (ARCH_SUN4C_SUN4 && len > 0x20000000) > return -ENOMEM; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp)) >+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; >+ else >+#endif >+ > if (!addr) > addr = TASK_UNMAPPED_BASE; > >@@ -225,6 +233,11 @@ > struct file * file = NULL; > unsigned long retval = -EBADF; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > if (!(flags & MAP_ANONYMOUS)) { > file = fget(fd); > if (!file) >@@ -243,6 +256,12 @@ > if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE) > goto out_putf; > >+ if (gr_handle_mmap(file, prot)) { >+ fput(file); >+ retval = -EACCES; >+ goto out; >+ } >+ > flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); > > down_write(¤t->mm->mmap_sem); >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc/kernel/sys_sunos.c linux-2.4.22-ppc-dev/arch/sparc/kernel/sys_sunos.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc/kernel/sys_sunos.c 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc/kernel/sys_sunos.c 2003-09-14 14:07:41.000000000 +0200 >@@ -68,6 +68,11 @@ > struct file * file = NULL; > unsigned long retval, ret_type; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > if(flags & MAP_NORESERVE) { > static int cnt; > if (cnt++ < 10) >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc/mm/fault.c linux-2.4.22-ppc-dev/arch/sparc/mm/fault.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc/mm/fault.c 2003-09-14 14:06:52.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc/mm/fault.c 2003-09-14 14:07:41.000000000 +0200 >@@ -19,6 +19,9 @@ > #include <linux/smp.h> > #include <linux/smp_lock.h> > #include <linux/interrupt.h> >+#include <linux/slab.h> >+#include <linux/pagemap.h> >+#include <linux/compiler.h> > > #include <asm/system.h> > #include <asm/segment.h> >@@ -200,6 +203,261 @@ > return 0; > } > >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+void pax_emuplt_close(struct vm_area_struct * vma) >+{ >+ vma->vm_mm->call_dl_resolve = 0UL; >+} >+ >+static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) >+{ >+ struct page* page; >+ unsigned int *kaddr; >+ >+ page = alloc_page(GFP_HIGHUSER); >+ if (!page) >+ return page; >+ >+ kaddr = kmap(page); >+ memset(kaddr, 0, PAGE_SIZE); >+ kaddr[0] = 0x9DE3BFA8U; /* save */ >+ flush_dcache_page(page); >+ kunmap(page); >+ return page; >+} >+ >+static struct vm_operations_struct pax_vm_ops = { >+ close: pax_emuplt_close, >+ nopage: pax_emuplt_nopage, >+}; >+ >+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) >+{ >+ vma->vm_mm = current->mm; >+ vma->vm_start = addr; >+ vma->vm_end = addr + PAGE_SIZE; >+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; >+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; >+ vma->vm_ops = &pax_vm_ops; >+ vma->vm_pgoff = 0UL; >+ vma->vm_file = NULL; >+ vma->vm_private_data = NULL; >+ insert_vm_struct(current->mm, vma); >+ ++current->mm->total_vm; >+} >+ >+/* >+ * PaX: decide what to do with offenders (regs->pc = fault address) >+ * >+ * returns 1 when task should be killed >+ * 2 when patched PLT trampoline was detected >+ * 3 when unpatched PLT trampoline was detected >+ * 4 when legitimate ET_EXEC was detected >+ */ >+static int pax_handle_fetch_fault(struct pt_regs *regs) >+{ >+ int err; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (current->flags & PF_PAX_RANDEXEC) { >+ if (regs->pc >= current->mm->start_code && >+ regs->pc < current->mm->end_code) >+ { >+ if (regs->u_regs[UREG_RETPC] + 8UL == regs->pc) >+ return 1; >+ >+ regs->pc += current->mm->delta_exec; >+ if (regs->npc >= current->mm->start_code && >+ regs->npc < current->mm->end_code) >+ regs->npc += current->mm->delta_exec; >+ return 4; >+ } >+ if (regs->pc >= current->mm->start_code + current->mm->delta_exec && >+ regs->pc < current->mm->end_code + current->mm->delta_exec) >+ { >+ regs->pc -= current->mm->delta_exec; >+ if (regs->npc >= current->mm->start_code + current->mm->delta_exec && >+ regs->npc < current->mm->end_code + current->mm->delta_exec) >+ regs->npc -= current->mm->delta_exec; >+ } >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ do { /* PaX: patched PLT emulation #1 */ >+ unsigned int sethi1, sethi2, jmpl; >+ >+ err = get_user(sethi1, (unsigned int *)regs->pc); >+ err |= get_user(sethi2, (unsigned int *)(regs->pc+4)); >+ err |= get_user(jmpl, (unsigned int *)(regs->pc+8)); >+ >+ if (err) >+ break; >+ >+ if ((sethi1 & 0xFFC00000U) == 0x03000000U && >+ (sethi2 & 0xFFC00000U) == 0x03000000U && >+ (jmpl & 0xFFFFE000U) == 0x81C06000U) >+ { >+ unsigned int addr; >+ >+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; >+ addr = regs->u_regs[UREG_G1]; >+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); >+ regs->pc = addr; >+ regs->npc = addr+4; >+ return 2; >+ } >+ } while (0); >+ >+ { /* PaX: patched PLT emulation #2 */ >+ unsigned int ba; >+ >+ err = get_user(ba, (unsigned int *)regs->pc); >+ >+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) { >+ unsigned int addr; >+ >+ addr = regs->pc + 4 + (((ba | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); >+ regs->pc = addr; >+ regs->npc = addr+4; >+ return 2; >+ } >+ } >+ >+ do { /* PaX: patched PLT emulation #3 */ >+ unsigned int sethi, jmpl, nop; >+ >+ err = get_user(sethi, (unsigned int*)regs->pc); >+ err |= get_user(jmpl, (unsigned int*)(regs->pc+4)); >+ err |= get_user(nop, (unsigned int*)(regs->pc+8)); >+ >+ if (err) >+ break; >+ if ((sethi & 0xFFC00000U) == 0x03000000U && >+ (jmpl & 0xFFFFE000U) == 0x81C06000U && >+ nop == 0x01000000U) >+ { >+ unsigned int addr; >+ >+ addr = (sethi & 0x003FFFFFU) << 10; >+ regs->u_regs[UREG_G1] = addr; >+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); >+ regs->pc = addr; >+ regs->npc = addr+4; >+ return 2; >+ } >+ } while (0); >+ >+ do { /* PaX: unpatched PLT emulation step 1 */ >+ unsigned int sethi, ba, nop; >+ >+ err = get_user(sethi, (unsigned int *)regs->pc); >+ err |= get_user(ba, (unsigned int *)(regs->pc+4)); >+ err |= get_user(nop, (unsigned int *)(regs->pc+8)); >+ >+ if (err) >+ break; >+ if ((sethi & 0xFFC00000U) == 0x03000000U && >+ (ba & 0xFFC00000U) == 0x30800000U && >+ nop == 0x01000000U) >+ { >+ unsigned int addr, save, call; >+ >+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); >+ >+ err = get_user(save, (unsigned int *)addr); >+ err |= get_user(call, (unsigned int *)(addr+4)); >+ err |= get_user(nop, (unsigned int *)(addr+8)); >+ if (err) >+ break; >+ >+ if (save == 0x9DE3BFA8U && >+ (call & 0xC0000000U) == 0x40000000U && >+ nop == 0x01000000U) >+ { >+ struct vm_area_struct *vma; >+ unsigned long call_dl_resolve; >+ >+ down_read(¤t->mm->mmap_sem); >+ call_dl_resolve = current->mm->call_dl_resolve; >+ up_read(¤t->mm->mmap_sem); >+ if (likely(call_dl_resolve)) >+ goto emulate; >+ >+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); >+ >+ down_write(¤t->mm->mmap_sem); >+ if (current->mm->call_dl_resolve) { >+ call_dl_resolve = current->mm->call_dl_resolve; >+ up_write(¤t->mm->mmap_sem); >+ if (vma) kmem_cache_free(vm_area_cachep, vma); >+ goto emulate; >+ } >+ >+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); >+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) { >+ up_write(¤t->mm->mmap_sem); >+ if (vma) kmem_cache_free(vm_area_cachep, vma); >+ return 1; >+ } >+ >+ pax_insert_vma(vma, call_dl_resolve); >+ current->mm->call_dl_resolve = call_dl_resolve; >+ up_write(¤t->mm->mmap_sem); >+ >+emulate: >+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; >+ regs->pc = call_dl_resolve; >+ regs->npc = addr+4; >+ return 3; >+ } >+ } >+ } while (0); >+ >+ do { /* PaX: unpatched PLT emulation step 2 */ >+ unsigned int save, call, nop; >+ >+ err = get_user(save, (unsigned int*)(regs->pc-4)); >+ err |= get_user(call, (unsigned int*)regs->pc); >+ err |= get_user(nop, (unsigned int*)(regs->pc+4)); >+ if (err) >+ break; >+ >+ if (save == 0x9DE3BFA8U && >+ (call & 0xC0000000U) == 0x40000000U && >+ nop == 0x01000000U) >+ { >+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2); >+ >+ regs->u_regs[UREG_RETPC] = regs->pc; >+ regs->pc = dl_resolve; >+ regs->npc = dl_resolve+4; >+ return 3; >+ } >+ } while (0); >+ >+#endif >+ >+ return 1; >+} >+ >+void pax_report_insns(void *pc) >+{ >+ unsigned long i; >+ >+ printk(KERN_ERR "PAX: bytes at PC: "); >+ for (i = 0; i < 5; i++) { >+ unsigned int c; >+ if (get_user(c, (unsigned int*)pc+i)) { >+ printk("<invalid address>."); >+ break; >+ } >+ printk("%08x ", c); >+ } >+ printk("\n"); >+} >+#endif >+ > asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, > unsigned long address) > { >@@ -263,6 +521,29 @@ > if(!(vma->vm_flags & VM_WRITE)) > goto bad_area; > } else { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if ((current->flags & PF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) { >+ up_read(&mm->mmap_sem); >+ switch (pax_handle_fetch_fault(regs)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ case 2: >+ case 3: >+ return; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ case 4: >+ return; >+#endif >+ >+ } >+ pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]); >+ do_exit(SIGKILL); >+ } >+#endif >+ > /* Allow reads even for write-only mappings */ > if(!(vma->vm_flags & (VM_READ | VM_EXEC))) > goto bad_area; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc/mm/init.c linux-2.4.22-ppc-dev/arch/sparc/mm/init.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc/mm/init.c 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc/mm/init.c 2003-09-14 14:07:41.000000000 +0200 >@@ -350,17 +350,17 @@ > > /* Initialize the protection map with non-constant, MMU dependent values. */ > protection_map[0] = PAGE_NONE; >- protection_map[1] = PAGE_READONLY; >- protection_map[2] = PAGE_COPY; >- protection_map[3] = PAGE_COPY; >+ protection_map[1] = PAGE_READONLY_NOEXEC; >+ protection_map[2] = PAGE_COPY_NOEXEC; >+ protection_map[3] = PAGE_COPY_NOEXEC; > protection_map[4] = PAGE_READONLY; > protection_map[5] = PAGE_READONLY; > protection_map[6] = PAGE_COPY; > protection_map[7] = PAGE_COPY; > protection_map[8] = PAGE_NONE; >- protection_map[9] = PAGE_READONLY; >- protection_map[10] = PAGE_SHARED; >- protection_map[11] = PAGE_SHARED; >+ protection_map[9] = PAGE_READONLY_NOEXEC; >+ protection_map[10] = PAGE_SHARED_NOEXEC; >+ protection_map[11] = PAGE_SHARED_NOEXEC; > protection_map[12] = PAGE_READONLY; > protection_map[13] = PAGE_READONLY; > protection_map[14] = PAGE_SHARED; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc/mm/srmmu.c linux-2.4.22-ppc-dev/arch/sparc/mm/srmmu.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc/mm/srmmu.c 2003-09-14 14:04:00.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc/mm/srmmu.c 2003-09-14 14:07:41.000000000 +0200 >@@ -2042,6 +2042,13 @@ > BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED)); > BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); > BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC)); >+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC)); >+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC)); >+#endif >+ > BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); > page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); > pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/config.in linux-2.4.22-ppc-dev/arch/sparc64/config.in >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/config.in 2003-09-14 14:04:07.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/config.in 2003-09-14 14:07:41.000000000 +0200 >@@ -311,3 +311,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 -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/ioctl32.c linux-2.4.22-ppc-dev/arch/sparc64/kernel/ioctl32.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/ioctl32.c 2003-09-14 14:04:07.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/kernel/ioctl32.c 2003-09-14 14:07:41.000000000 +0200 >@@ -2046,7 +2046,11 @@ > * To have permissions to do most of the vt ioctls, we either have > * to be the owner of the tty, or super-user. > */ >+#ifdef CONFIG_GRKERNSEC >+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) >+#else > if (current->tty == tty || suser()) >+#endif > return 1; > return 0; > } >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/itlb_base.S linux-2.4.22-ppc-dev/arch/sparc64/kernel/itlb_base.S >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/itlb_base.S 2003-09-14 14:04:07.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/kernel/itlb_base.S 2003-09-14 14:07:41.000000000 +0200 >@@ -41,7 +41,9 @@ > CREATE_VPTE_OFFSET2(%g4, %g6) ! Create VPTE offset > ldxa [%g3 + %g6] ASI_P, %g5 ! Load VPTE > 1: brgez,pn %g5, 3f ! Not valid, branch out >- nop ! Delay-slot >+ and %g5, _PAGE_EXEC, %g4 >+ brz,pn %g4, 3f ! Not executable, branch out >+ nop ! Delay-slot > 2: stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load PTE into TLB > retry ! Trap return > 3: rdpr %pstate, %g4 ! Move into alternate globals >@@ -74,8 +76,6 @@ > nop > nop > nop >- nop >- nop > CREATE_VPTE_NOP > > #undef CREATE_VPTE_OFFSET1 >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/ptrace.c linux-2.4.22-ppc-dev/arch/sparc64/kernel/ptrace.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/ptrace.c 2003-09-14 14:04:07.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/kernel/ptrace.c 2003-09-14 14:07:41.000000000 +0200 >@@ -18,6 +18,7 @@ > #include <linux/user.h> > #include <linux/smp.h> > #include <linux/smp_lock.h> >+#include <linux/grsecurity.h> > > #include <asm/asi.h> > #include <asm/pgtable.h> >@@ -161,6 +162,11 @@ > goto out; > } > >+ if (gr_handle_ptrace(child, (long)request)) { >+ pt_error_return(regs, EPERM); >+ goto out; >+ } >+ > if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) > || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { > if (ptrace_attach(child)) { >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/sys_sparc.c linux-2.4.22-ppc-dev/arch/sparc64/kernel/sys_sparc.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/sys_sparc.c 2003-09-14 14:04:07.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/kernel/sys_sparc.c 2003-09-14 14:07:41.000000000 +0200 >@@ -24,6 +24,7 @@ > #include <linux/slab.h> > #include <linux/ipc.h> > #include <linux/personality.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/ipc.h> >@@ -63,6 +64,13 @@ > task_size = 0xf0000000UL; > if (len > task_size || len > -PAGE_OFFSET) > return -ENOMEM; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ if ((current->flags & PF_PAX_RANDMMAP) && (!addr || filp)) >+ addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; >+ else >+#endif >+ > if (!addr) > addr = TASK_UNMAPPED_BASE; > >@@ -289,11 +297,22 @@ > struct file * file = NULL; > unsigned long retval = -EBADF; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > if (!(flags & MAP_ANONYMOUS)) { > file = fget(fd); > if (!file) > goto out; > } >+ >+ if (gr_handle_mmap(file, prot)) { >+ retval = -EACCES; >+ goto out_putf; >+ } >+ > flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); > len = PAGE_ALIGN(len); > retval = -EINVAL; >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/sys_sparc32.c linux-2.4.22-ppc-dev/arch/sparc64/kernel/sys_sparc32.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/sys_sparc32.c 2003-09-14 14:04:07.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/kernel/sys_sparc32.c 2003-09-14 14:07:41.000000000 +0200 >@@ -52,6 +52,8 @@ > #include <linux/sysctl.h> > #include <linux/dnotify.h> > #include <linux/netfilter_ipv4/ip_tables.h> >+#include <linux/random.h> >+#include <linux/grsecurity.h> > > #include <asm/types.h> > #include <asm/ipc.h> >@@ -3233,8 +3235,18 @@ > struct file * file; > int retval; > int i; >+#ifdef CONFIG_GRKERNSEC >+ struct file *old_exec_file; >+ struct acl_subject_label *old_acl; >+ struct rlimit old_rlim[RLIM_NLIMITS]; >+#endif > > bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK >+ bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK; >+#endif >+ > memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0])); > > file = open_exec(filename); >@@ -3243,6 +3255,20 @@ > if (IS_ERR(file)) > return retval; > >+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes)); >+ >+ if (gr_handle_nproc()) { >+ allow_write_access(file); >+ fput(file); >+ return -EAGAIN; >+ } >+ >+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) { >+ allow_write_access(file); >+ fput(file); >+ return -EACCES; >+ } >+ > bprm.file = file; > bprm.filename = filename; > bprm.sh_bang = 0; >@@ -3263,11 +3289,24 @@ > if (retval < 0) > goto out; > >+ if(!gr_tpe_allow(file)) { >+ retval = -EACCES; >+ goto out; >+ } >+ >+ if (gr_check_crash_exec(file)) { >+ retval = -EACCES; >+ goto out; >+ } >+ > retval = copy_strings_kernel(1, &bprm.filename, &bprm); > if (retval < 0) > goto out; > > bprm.exec = bprm.p; >+ >+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); >+ > retval = copy_strings32(bprm.envc, envp, &bprm); > if (retval < 0) > goto out; >@@ -3276,11 +3315,32 @@ > if (retval < 0) > goto out; > >+#ifdef CONFIG_GRKERNSEC >+ old_acl = current->acl; >+ memcpy(old_rlim, current->rlim, sizeof(old_rlim)); >+ old_exec_file = current->exec_file; >+ get_file(file); >+ current->exec_file = file; >+#endif >+ >+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt); >+ > 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 >+ current->acl = old_acl; >+ memcpy(current->rlim, old_rlim, sizeof(old_rlim)); >+ 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 -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/sys_sunos32.c linux-2.4.22-ppc-dev/arch/sparc64/kernel/sys_sunos32.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/kernel/sys_sunos32.c 2003-09-14 14:04:07.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/kernel/sys_sunos32.c 2003-09-14 14:07:41.000000000 +0200 >@@ -68,6 +68,11 @@ > struct file *file = NULL; > unsigned long retval, ret_type; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > if(flags & MAP_NORESERVE) { > static int cnt; > if (cnt++ < 10) >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/mm/fault.c linux-2.4.22-ppc-dev/arch/sparc64/mm/fault.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/mm/fault.c 2003-09-14 14:06:52.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/mm/fault.c 2003-09-14 14:07:41.000000000 +0200 >@@ -16,6 +16,9 @@ > #include <linux/smp_lock.h> > #include <linux/init.h> > #include <linux/interrupt.h> >+#include <linux/slab.h> >+#include <linux/pagemap.h> >+#include <linux/compiler.h> > > #include <asm/page.h> > #include <asm/pgtable.h> >@@ -299,6 +302,267 @@ > unhandled_fault (address, current, regs); > } > >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+static void pax_emuplt_close(struct vm_area_struct * vma) >+{ >+ vma->vm_mm->call_dl_resolve = 0UL; >+} >+ >+static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) >+{ >+ struct page* page; >+ unsigned int *kaddr; >+ >+ page = alloc_page(GFP_HIGHUSER); >+ if (!page) >+ return page; >+ >+ kaddr = kmap(page); >+ memset(kaddr, 0, PAGE_SIZE); >+ kaddr[0] = 0x9DE3BFA8U; /* save */ >+ flush_dcache_page(page); >+ kunmap(page); >+ return page; >+} >+ >+static struct vm_operations_struct pax_vm_ops = { >+ close: pax_emuplt_close, >+ nopage: pax_emuplt_nopage, >+}; >+ >+static void pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) >+{ >+ vma->vm_mm = current->mm; >+ vma->vm_start = addr; >+ vma->vm_end = addr + PAGE_SIZE; >+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; >+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; >+ vma->vm_ops = &pax_vm_ops; >+ vma->vm_pgoff = 0UL; >+ vma->vm_file = NULL; >+ vma->vm_private_data = NULL; >+ insert_vm_struct(current->mm, vma); >+ ++current->mm->total_vm; >+} >+#endif >+ >+/* >+ * PaX: decide what to do with offenders (regs->tpc = fault address) >+ * >+ * returns 1 when task should be killed >+ * 2 when patched PLT trampoline was detected >+ * 3 when unpatched PLT trampoline was detected >+ * 4 when legitimate ET_EXEC was detected >+ */ >+static int pax_handle_fetch_fault(struct pt_regs *regs) >+{ >+ int err; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (current->flags & PF_PAX_RANDEXEC) { >+ if (regs->tpc >= current->mm->start_code && >+ regs->tpc < current->mm->end_code) >+ { >+ if (regs->u_regs[UREG_RETPC] + 8UL == regs->tpc) >+ return 1; >+ >+ regs->tpc += current->mm->delta_exec; >+ if (regs->tnpc >= current->mm->start_code && >+ regs->tnpc < current->mm->end_code) >+ regs->tnpc += current->mm->delta_exec; >+ return 4; >+ } >+ if (regs->tpc >= current->mm->start_code + current->mm->delta_exec && >+ regs->tpc < current->mm->end_code + current->mm->delta_exec) >+ { >+ regs->tpc -= current->mm->delta_exec; >+ if (regs->tnpc >= current->mm->start_code + current->mm->delta_exec && >+ regs->tnpc < current->mm->end_code + current->mm->delta_exec) >+ regs->tnpc -= current->mm->delta_exec; >+ } >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ do { /* PaX: patched PLT emulation #1 */ >+ unsigned int sethi1, sethi2, jmpl; >+ >+ err = get_user(sethi1, (unsigned int*)regs->tpc); >+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4)); >+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+8)); >+ >+ if (err) >+ break; >+ >+ if ((sethi1 & 0xFFC00000U) == 0x03000000U && >+ (sethi2 & 0xFFC00000U) == 0x03000000U && >+ (jmpl & 0xFFFFE000U) == 0x81C06000U) >+ { >+ unsigned long addr; >+ >+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; >+ addr = regs->u_regs[UREG_G1]; >+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); >+ regs->tpc = addr; >+ regs->tnpc = addr+4; >+ return 2; >+ } >+ } while (0); >+ >+ { /* PaX: patched PLT emulation #2 */ >+ unsigned int ba; >+ >+ err = get_user(ba, (unsigned int*)regs->tpc); >+ >+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) { >+ unsigned long addr; >+ >+ addr = regs->tpc + 4 + (((ba | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); >+ regs->tpc = addr; >+ regs->tnpc = addr+4; >+ return 2; >+ } >+ } >+ >+ do { /* PaX: patched PLT emulation #3 */ >+ unsigned int sethi, jmpl, nop; >+ >+ err = get_user(sethi, (unsigned int*)regs->tpc); >+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+4)); >+ err |= get_user(nop, (unsigned int*)(regs->tpc+8)); >+ >+ if (err) >+ break; >+ >+ if ((sethi & 0xFFC00000U) == 0x03000000U && >+ (jmpl & 0xFFFFE000U) == 0x81C06000U && >+ nop == 0x01000000U) >+ { >+ unsigned long addr; >+ >+ addr = (sethi & 0x003FFFFFU) << 10; >+ regs->u_regs[UREG_G1] = addr; >+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); >+ regs->tpc = addr; >+ regs->tnpc = addr+4; >+ return 2; >+ } >+ } while (0); >+ >+ do { /* PaX: unpatched PLT emulation step 1 */ >+ unsigned int sethi, ba, nop; >+ >+ err = get_user(sethi, (unsigned int*)regs->tpc); >+ err |= get_user(ba, (unsigned int*)(regs->tpc+4)); >+ err |= get_user(nop, (unsigned int*)(regs->tpc+8)); >+ >+ if (err) >+ break; >+ >+ if ((sethi & 0xFFC00000U) == 0x03000000U && >+ (ba & 0xFFC00000U) == 0x30800000U && >+ nop == 0x01000000U) >+ { >+ unsigned long addr; >+ unsigned int save, call; >+ >+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); >+ >+ err = get_user(save, (unsigned int*)addr); >+ err |= get_user(call, (unsigned int*)(addr+4)); >+ err |= get_user(nop, (unsigned int*)(addr+8)); >+ >+ if (err) >+ break; >+ >+ if (save == 0x9DE3BFA8U && >+ (call & 0xC0000000U) == 0x40000000U && >+ nop == 0x01000000U) >+ { >+ struct vm_area_struct *vma; >+ unsigned long call_dl_resolve; >+ >+ down_read(¤t->mm->mmap_sem); >+ call_dl_resolve = current->mm->call_dl_resolve; >+ up_read(¤t->mm->mmap_sem); >+ if (likely(call_dl_resolve)) >+ goto emulate; >+ >+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); >+ >+ down_write(¤t->mm->mmap_sem); >+ if (current->mm->call_dl_resolve) { >+ call_dl_resolve = current->mm->call_dl_resolve; >+ up_write(¤t->mm->mmap_sem); >+ if (vma) kmem_cache_free(vm_area_cachep, vma); >+ goto emulate; >+ } >+ >+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); >+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) { >+ up_write(¤t->mm->mmap_sem); >+ if (vma) kmem_cache_free(vm_area_cachep, vma); >+ return 1; >+ } >+ >+ pax_insert_vma(vma, call_dl_resolve); >+ current->mm->call_dl_resolve = call_dl_resolve; >+ up_write(¤t->mm->mmap_sem); >+ >+emulate: >+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; >+ regs->tpc = call_dl_resolve; >+ regs->tnpc = addr+4; >+ return 3; >+ } >+ } >+ } while (0); >+ >+ do { /* PaX: unpatched PLT emulation step 2 */ >+ unsigned int save, call, nop; >+ >+ err = get_user(save, (unsigned int*)(regs->tpc-4)); >+ err |= get_user(call, (unsigned int*)regs->tpc); >+ err |= get_user(nop, (unsigned int*)(regs->tpc+4)); >+ if (err) >+ break; >+ >+ if (save == 0x9DE3BFA8U && >+ (call & 0xC0000000U) == 0x40000000U && >+ nop == 0x01000000U) >+ { >+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); >+ >+ regs->u_regs[UREG_RETPC] = regs->tpc; >+ regs->tpc = dl_resolve; >+ regs->tnpc = dl_resolve+4; >+ return 3; >+ } >+ } while (0); >+#endif >+ >+ return 1; >+} >+ >+void pax_report_insns(void *pc) >+{ >+ unsigned long i; >+ >+ printk(KERN_ERR "PAX: bytes at PC: "); >+ for (i = 0; i < 5; i++) { >+ unsigned int c; >+ if (get_user(c, (unsigned int*)pc+i)) { >+ printk("<invalid address>."); >+ break; >+ } >+ printk("%08x ", c); >+ } >+ printk("\n"); >+} >+#endif >+ >+ > asmlinkage void do_sparc64_fault(struct pt_regs *regs) > { > struct mm_struct *mm = current->mm; >@@ -338,6 +602,7 @@ > > if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { > regs->tpc &= 0xffffffff; >+ regs->tnpc &= 0xffffffff; > address &= 0xffffffff; > } > >@@ -346,6 +611,34 @@ > if (!vma) > goto bad_area; > >+ /* PaX: detect ITLB misses on non-exec pages */ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if ((current->flags & PF_PAX_PAGEEXEC) && vma->vm_start <= address && >+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB)) >+ { >+ if (address != regs->tpc) >+ goto good_area; >+ >+ up_read(&mm->mmap_sem); >+ switch (pax_handle_fetch_fault(regs)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUPLT >+ case 2: >+ case 3: >+ goto fault_done; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ case 4: >+ goto fault_done; >+#endif >+ >+ } >+ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS)); >+ do_exit(SIGKILL); >+ } >+#endif >+ > /* Pure DTLB misses do not tell us whether the fault causing > * load/store/atomic was a write or not, it only says that there > * was no match. So in such a case we (carefully) read the >diff -Naur linux-2.4.22-ppc-dev.orig/arch/sparc64/solaris/misc.c linux-2.4.22-ppc-dev/arch/sparc64/solaris/misc.c >--- linux-2.4.22-ppc-dev.orig/arch/sparc64/solaris/misc.c 2003-09-14 14:04:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/sparc64/solaris/misc.c 2003-09-14 14:07:41.000000000 +0200 >@@ -53,6 +53,11 @@ > struct file *file = NULL; > unsigned long retval, ret_type; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (flags & MAP_MIRROR) >+ return -EINVAL; >+#endif >+ > /* Do we need it here? */ > set_personality(PER_SVR4); > if (flags & MAP_NORESERVE) { >diff -Naur linux-2.4.22-ppc-dev.orig/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.22-ppc-dev/arch/x86_64/ia32/ia32_ioctl.c >--- linux-2.4.22-ppc-dev.orig/arch/x86_64/ia32/ia32_ioctl.c 2003-09-14 14:03:57.000000000 +0200 >+++ linux-2.4.22-ppc-dev/arch/x86_64/ia32/ia32_ioctl.c 2003-09-14 14:07:41.000000000 +0200 >@@ -1932,7 +1932,11 @@ > * To have permissions to do most of the vt ioctls, we either have > * to be the owner of the tty, or super-user. > */ >+#ifdef CONFIG_GRKERNSEC >+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) >+#else > if (current->tty == tty || suser()) >+#endif > return 1; > return 0; > } >diff -Naur linux-2.4.22-ppc-dev.orig/drivers/char/keyboard.c linux-2.4.22-ppc-dev/drivers/char/keyboard.c >--- linux-2.4.22-ppc-dev.orig/drivers/char/keyboard.c 2003-09-14 14:03:31.000000000 +0200 >+++ linux-2.4.22-ppc-dev/drivers/char/keyboard.c 2003-09-14 14:07:41.000000000 +0200 >@@ -533,6 +533,16 @@ > if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) && > !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value))) > return; >+ >+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP) >+ { >+ void *func = spec_fn_table[value]; >+ if (func == show_state || func == show_ptregs || >+ func == show_mem) >+ return; >+ } >+#endif >+ > spec_fn_table[value](); > } > >diff -Naur linux-2.4.22-ppc-dev.orig/drivers/char/mem.c linux-2.4.22-ppc-dev/drivers/char/mem.c >--- linux-2.4.22-ppc-dev.orig/drivers/char/mem.c 2003-09-14 14:03:31.000000000 +0200 >+++ linux-2.4.22-ppc-dev/drivers/char/mem.c 2003-09-14 14:07:41.000000000 +0200 >@@ -21,6 +21,7 @@ > #include <linux/raw.h> > #include <linux/tty.h> > #include <linux/capability.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/io.h> >@@ -41,6 +42,10 @@ > #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR) > extern void tapechar_init(void); > #endif >+ >+#ifdef CONFIG_GRKERNSEC >+extern struct file_operations grsec_fops; >+#endif > > static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp, > const char * buf, size_t count, loff_t *ppos) >@@ -114,6 +119,11 @@ > unsigned long p = *ppos; > unsigned long end_mem; > >+#ifdef CONFIG_GRKERNSEC_KMEM >+ gr_handle_mem_write(); >+ return -EPERM; >+#endif >+ > end_mem = __pa(high_memory); > if (p >= end_mem) > return 0; >@@ -186,6 +196,12 @@ > { > unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; > >+#ifdef CONFIG_GRKERNSEC_KMEM >+ if (gr_handle_mem_mmap(offset, vma)) >+ return -EPERM; >+#endif >+ >+ > /* > * Accessing memory above the top the kernel knows about or > * through a file pointer that was marked O_SYNC will be >@@ -285,6 +301,11 @@ > ssize_t virtr = 0; > char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ > >+#ifdef CONFIG_GRKERNSEC_KMEM >+ gr_handle_kmem_write(); >+ return -EPERM; >+#endif >+ > if (p < (unsigned long) high_memory) { > wrote = count; > if (count > (unsigned long) high_memory - p) >@@ -401,7 +422,7 @@ > count = size; > > zap_page_range(mm, addr, count); >- zeromap_page_range(addr, count, PAGE_COPY); >+ zeromap_page_range(addr, count, vma->vm_page_prot); > > size -= count; > buf += count; >@@ -517,6 +538,15 @@ > > static int open_port(struct inode * inode, struct file * filp) > { >+#ifdef CONFIG_GRKERNSEC_KMEM >+ gr_handle_open_port(); >+ return -EPERM; >+#endif >+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; >+} >+ >+static int open_mem(struct inode * inode, struct file * filp) >+{ > return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; > } > >@@ -574,6 +604,11 @@ > unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; > unsigned long size = vma->vm_end - vma->vm_start; > >+#ifdef CONFIG_GRKERNSEC_KMEM >+ if (gr_handle_mem_mmap(offset, vma)) >+ return -EPERM; >+#endif >+ > /* > * If the user is not attempting to mmap a high memory address then > * the standard mmap_mem mechanism will work. High memory addresses >@@ -609,7 +644,6 @@ > #define full_lseek null_lseek > #define write_zero write_null > #define read_full read_zero >-#define open_mem open_port > #define open_kmem open_mem > > static struct file_operations mem_fops = { >@@ -685,6 +719,11 @@ > case 9: > filp->f_op = &urandom_fops; > break; >+#ifdef CONFIG_GRKERNSEC >+ case 10: >+ filp->f_op = &grsec_fops; >+ break; >+#endif > default: > return -ENXIO; > } >@@ -711,7 +750,10 @@ > {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, > {7, "full", S_IRUGO | S_IWUGO, &full_fops}, > {8, "random", S_IRUGO | S_IWUSR, &random_fops}, >- {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops} >+ {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, >+#ifdef CONFIG_GRKERNSEC >+ {10,"grsec", S_IRUSR | S_IWUGO, &grsec_fops} >+#endif > }; > int i; > >diff -Naur linux-2.4.22-ppc-dev.orig/drivers/char/random.c linux-2.4.22-ppc-dev/drivers/char/random.c >--- linux-2.4.22-ppc-dev.orig/drivers/char/random.c 2003-09-14 14:03:31.000000000 +0200 >+++ linux-2.4.22-ppc-dev/drivers/char/random.c 2003-09-14 14:07:41.000000000 +0200 >@@ -262,9 +262,15 @@ > /* > * Configuration information > */ >+#ifdef CONFIG_GRKERNSEC_RANDNET >+#define DEFAULT_POOL_SIZE 1024 >+#define SECONDARY_POOL_SIZE 256 >+#define BATCH_ENTROPY_SIZE 512 >+#else > #define DEFAULT_POOL_SIZE 512 > #define SECONDARY_POOL_SIZE 128 > #define BATCH_ENTROPY_SIZE 256 >+#endif > #define USE_SHA > > /* >@@ -389,6 +395,7 @@ > /* > * Static global variables > */ >+ > static struct entropy_store *random_state; /* The default global store */ > static struct entropy_store *sec_random_state; /* secondary store */ > static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); >@@ -2202,6 +2209,29 @@ > return halfMD4Transform(hash, keyptr->secret); > } > >+#ifdef CONFIG_GRKERNSEC >+/* the following function is provided by PaX under the GPL */ >+unsigned long get_random_long(void) >+{ >+ static time_t rekey_time; >+ static __u32 secret[12]; >+ time_t t; >+ >+ /* >+ * Pick a random secret every REKEY_INTERVAL seconds >+ */ >+ t = CURRENT_TIME; >+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) { >+ rekey_time = t; >+ get_random_bytes(secret, sizeof(secret)); >+ } >+ >+ secret[1] = halfMD4Transform(secret+8, secret); >+ secret[0] = halfMD4Transform(secret+8, secret); >+ return *(unsigned long *)secret; >+} >+#endif >+ > #ifdef CONFIG_SYN_COOKIES > /* > * Secure SYN cookie computation. This is the algorithm worked out by >diff -Naur linux-2.4.22-ppc-dev.orig/drivers/char/tty_io.c linux-2.4.22-ppc-dev/drivers/char/tty_io.c >--- linux-2.4.22-ppc-dev.orig/drivers/char/tty_io.c 2003-09-14 14:03:31.000000000 +0200 >+++ linux-2.4.22-ppc-dev/drivers/char/tty_io.c 2003-09-14 14:07:41.000000000 +0200 >@@ -99,7 +99,7 @@ > #include <linux/vt_kern.h> > #include <linux/selection.h> > #include <linux/devfs_fs_kernel.h> >- >+#include <linux/grsecurity.h> > #include <linux/kmod.h> > > #ifdef CONFIG_VT >@@ -1402,7 +1402,11 @@ > retval = -ENODEV; > filp->f_flags = saved_flags; > >+#ifdef CONFIG_GRKERNSEC >+ if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_TTY_CONFIG)) >+#else > if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser()) >+#endif > retval = -EBUSY; > > if (retval) { >@@ -1504,7 +1508,11 @@ > { > char ch, mbz = 0; > >+#ifdef CONFIG_GRKERNSEC >+ if ((current->tty != tty) && !capable(CAP_SYS_TTY_CONFIG)) >+#else > if ((current->tty != tty) && !suser()) >+#endif > return -EPERM; > if (get_user(ch, arg)) > return -EFAULT; >@@ -1542,7 +1550,11 @@ > if (inode->i_rdev == SYSCONS_DEV || > inode->i_rdev == CONSOLE_DEV) { > struct file *f; >+#ifdef CONFIG_GRKERNSEC >+ if (!capable(CAP_SYS_TTY_CONFIG)) >+#else > if (!suser()) >+#endif > return -EPERM; > spin_lock(&redirect_lock); > f = redirect; >@@ -1594,7 +1606,11 @@ > * This tty is already the controlling > * tty for another session group! > */ >+#ifdef CONFIG_GRKERNSEC >+ if ((arg == 1) && capable(CAP_SYS_ADMIN)) { >+#else > if ((arg == 1) && suser()) { >+#endif > /* > * Steal it away > */ >diff -Naur linux-2.4.22-ppc-dev.orig/drivers/char/vt.c linux-2.4.22-ppc-dev/drivers/char/vt.c >--- linux-2.4.22-ppc-dev.orig/drivers/char/vt.c 2003-09-14 14:03:31.000000000 +0200 >+++ linux-2.4.22-ppc-dev/drivers/char/vt.c 2003-09-14 14:07:41.000000000 +0200 >@@ -32,6 +32,7 @@ > #include <linux/vt_kern.h> > #include <linux/kbd_diacr.h> > #include <linux/selection.h> >+#include <linux/grsecurity.h> > > #ifdef CONFIG_FB_COMPAT_XPMAC > #include <asm/vc_ioctl.h> >@@ -443,7 +444,11 @@ > * to be the owner of the tty, or super-user. > */ > perm = 0; >+#ifdef CONFIG_GRKERNSEC >+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) >+#else > if (current->tty == tty || suser()) >+#endif > perm = 1; > > kbd = kbd_table + console; >@@ -1038,12 +1043,20 @@ > return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm); > > case VT_LOCKSWITCH: >+#ifdef CONFIG_GRKERNSEC >+ if (!capable(CAP_SYS_TTY_CONFIG)) >+#else > if (!suser()) >+#endif > return -EPERM; > vt_dont_switch = 1; > return 0; > case VT_UNLOCKSWITCH: >+#ifdef CONFIG_GRKERNSEC >+ if (!capable(CAP_SYS_TTY_CONFIG)) >+#else > if (!suser()) >+#endif > return -EPERM; > vt_dont_switch = 0; > return 0; >diff -Naur linux-2.4.22-ppc-dev.orig/drivers/pci/proc.c linux-2.4.22-ppc-dev/drivers/pci/proc.c >--- linux-2.4.22-ppc-dev.orig/drivers/pci/proc.c 2003-09-14 14:03:41.000000000 +0200 >+++ linux-2.4.22-ppc-dev/drivers/pci/proc.c 2003-09-14 14:07:41.000000000 +0200 >@@ -562,7 +562,15 @@ > pci_for_each_dev(dev) { > pci_proc_attach_device(dev); > } >+#ifdef CONFIG_GRKERNSEC_PROC_ADD >+#ifdef CONFIG_GRKERNSEC_PROC_USER >+ entry = create_proc_entry("pci", S_IRUSR, NULL); >+#elif CONFIG_GRKERNSEC_PROC_USERGROUP >+ entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL); >+#endif >+#else > entry = create_proc_entry("pci", 0, NULL); >+#endif > if (entry) > entry->proc_fops = &proc_pci_operations; > } >diff -Naur linux-2.4.22-ppc-dev.orig/fs/binfmt_aout.c linux-2.4.22-ppc-dev/fs/binfmt_aout.c >--- linux-2.4.22-ppc-dev.orig/fs/binfmt_aout.c 2003-09-14 14:03:07.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/binfmt_aout.c 2003-09-14 14:07:41.000000000 +0200 >@@ -5,6 +5,7 @@ > */ > > #include <linux/module.h> >+#include <linux/config.h> > > #include <linux/sched.h> > #include <linux/kernel.h> >@@ -113,10 +114,12 @@ > /* If the size of the dump file exceeds the rlimit, then see what would happen > if we wrote the stack, but not the data area. */ > #ifdef __sparc__ >+ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize); > if ((dump.u_dsize+dump.u_ssize) > > current->rlim[RLIMIT_CORE].rlim_cur) > dump.u_dsize = 0; > #else >+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE); > if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE > > current->rlim[RLIMIT_CORE].rlim_cur) > dump.u_dsize = 0; >@@ -124,10 +127,12 @@ > > /* Make sure we have enough room to write the stack and data areas. */ > #ifdef __sparc__ >+ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize); > if ((dump.u_ssize) > > current->rlim[RLIMIT_CORE].rlim_cur) > dump.u_ssize = 0; > #else >+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE); > if ((dump.u_ssize+1) * PAGE_SIZE > > current->rlim[RLIMIT_CORE].rlim_cur) > dump.u_ssize = 0; >@@ -276,6 +281,8 @@ > rlim = current->rlim[RLIMIT_DATA].rlim_cur; > if (rlim >= RLIM_INFINITY) > rlim = ~0; >+ >+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss); > if (ex.a_data + ex.a_bss > rlim) > return -ENOMEM; > >@@ -307,6 +314,24 @@ > current->mm->mmap = NULL; > compute_creds(bprm); > current->flags &= ~PF_FORKNOEXEC; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) { >+ current->flags |= PF_PAX_PAGEEXEC; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP) >+ current->flags |= PF_PAX_EMUTRAMP; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT)) >+ current->flags |= PF_PAX_MPROTECT; >+#endif >+ >+ } >+#endif >+ > #ifdef __sparc__ > if (N_MAGIC(ex) == NMAGIC) { > loff_t pos = fd_offset; >@@ -393,7 +418,7 @@ > > down_write(¤t->mm->mmap_sem); > error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, >- PROT_READ | PROT_WRITE | PROT_EXEC, >+ PROT_READ | PROT_WRITE, > MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, > fd_offset + ex.a_text); > up_write(¤t->mm->mmap_sem); >diff -Naur linux-2.4.22-ppc-dev.orig/fs/binfmt_elf.c linux-2.4.22-ppc-dev/fs/binfmt_elf.c >--- linux-2.4.22-ppc-dev.orig/fs/binfmt_elf.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/binfmt_elf.c 2003-09-14 14:07:41.000000000 +0200 >@@ -11,6 +11,7 @@ > > #include <linux/module.h> > >+#include <linux/config.h> > #include <linux/fs.h> > #include <linux/stat.h> > #include <linux/sched.h> >@@ -33,10 +34,13 @@ > #include <linux/smp_lock.h> > #include <linux/compiler.h> > #include <linux/highmem.h> >+#include <linux/random.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/param.h> > #include <asm/pgalloc.h> >+#include <asm/system.h> > > #define DLINFO_ITEMS 13 > >@@ -86,6 +90,12 @@ > if (end <= start) > return; > do_brk(start, end - start); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (current->flags & PF_PAX_RANDEXEC) >+ do_mmap_pgoff(NULL, ELF_PAGEALIGN(start + current->mm->delta_exec), 0UL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, start); >+#endif >+ > } > > >@@ -445,6 +455,11 @@ > struct exec interp_ex; > char passed_fileno[6]; > struct files_struct *files; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ unsigned long load_addr_random = 0UL; >+ unsigned long load_bias_random = 0UL; >+#endif > > /* Get the exec-header */ > elf_ex = *((struct elfhdr *) bprm->buf); >@@ -617,7 +632,63 @@ > current->mm->end_data = 0; > current->mm->end_code = 0; > current->mm->mmap = NULL; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+ current->mm->delta_mmap = 0UL; >+ current->mm->delta_exec = 0UL; >+ current->mm->delta_stack = 0UL; >+#endif >+ > current->flags &= ~PF_FORKNOEXEC; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_PAGEEXEC)) { >+ current->flags |= PF_PAX_PAGEEXEC; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE >+ current->mm->call_dl_resolve = 0UL; >+#endif >+ >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) { >+ current->flags &= ~PF_PAX_PAGEEXEC; >+ current->flags |= PF_PAX_SEGMEXEC; >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ if (elf_ex.e_ident[EI_PAX] & EF_PAX_EMUTRAMP) >+ current->flags |= PF_PAX_EMUTRAMP; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+ if ((current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) && !(elf_ex.e_ident[EI_PAX] & EF_PAX_MPROTECT)) >+ current->flags |= PF_PAX_MPROTECT; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+ if (!(elf_ex.e_ident[EI_PAX] & EF_PAX_RANDMMAP)) { >+ current->flags |= PF_PAX_RANDMMAP; >+ >+#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb)) >+ >+ current->mm->delta_mmap = pax_delta_mask(get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current)); >+ current->mm->delta_exec = pax_delta_mask(get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current)); >+ current->mm->delta_stack = pax_delta_mask(get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current)); >+ } >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if ((elf_ex.e_ident[EI_PAX] & EF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC) && >+ (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC))) >+ current->flags |= PF_PAX_RANDEXEC; >+#endif >+ >+ gr_set_pax_flags(current); >+ > elf_entry = (unsigned long) elf_ex.e_entry; > > /* Do this so that we can load the interpreter, if need be. We will >@@ -673,11 +744,84 @@ > base, as well as whatever program they might try to exec. This > is because the brk will follow the loader, and is not movable. */ > load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ /* PaX: randomize base address at the default exe base if requested */ >+ if (current->flags & PF_PAX_RANDMMAP) { >+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec); >+ elf_flags |= MAP_FIXED; >+ } >+#endif >+ > } > >- error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags); >- if (BAD_ADDR(error)) >- continue; >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if ((current->flags & PF_PAX_RANDEXEC) && (elf_ex.e_type == ET_EXEC)) { >+ unsigned long addr, len; >+ >+ error = -ENOMEM; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (current->flags & PF_PAX_PAGEEXEC) >+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot & ~PROT_EXEC, elf_flags); >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if (current->flags & PF_PAX_SEGMEXEC) { >+ addr = ELF_PAGESTART(load_bias + vaddr); >+ len = elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr); >+ if (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len) >+ continue; >+ down_write(¤t->mm->mmap_sem); >+ error = do_mmap_pgoff(bprm->file, addr, len, elf_prot, elf_flags, (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT); >+ up_write(¤t->mm->mmap_sem); >+ } >+#endif >+ >+ if (BAD_ADDR(error)) >+ continue; >+ >+ /* PaX: mirror at a randomized base */ >+ down_write(¤t->mm->mmap_sem); >+ >+ if (!load_addr_set) { >+ load_addr_random = get_unmapped_area(bprm->file, 0UL, elf_ppnt->p_filesz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), (elf_ppnt->p_offset - ELF_PAGEOFFSET(elf_ppnt->p_vaddr)) >> PAGE_SHIFT, MAP_PRIVATE); >+ if (BAD_ADDR(load_addr_random)) { >+ up_write(¤t->mm->mmap_sem); >+ continue; >+ } >+ load_bias_random = load_addr_random - vaddr; >+ } >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (current->flags & PF_PAX_PAGEEXEC) >+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error); >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if (current->flags & PF_PAX_SEGMEXEC) { >+ if (elf_prot & PROT_EXEC) { >+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), elf_ppnt->p_memsz + ELF_PAGEOFFSET(elf_ppnt->p_vaddr), PROT_NONE, MAP_PRIVATE | MAP_FIXED, 0UL); >+ if (!BAD_ADDR(load_addr_random)) { >+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr + SEGMEXEC_TASK_SIZE), 0UL, elf_prot, elf_flags | MAP_MIRROR, error); >+ if (!BAD_ADDR(load_addr_random)) >+ load_addr_random -= SEGMEXEC_TASK_SIZE; >+ } >+ } else >+ load_addr_random = do_mmap_pgoff(NULL, ELF_PAGESTART(load_bias_random + vaddr), 0UL, elf_prot, elf_flags | MAP_MIRROR, error); >+ } >+#endif >+ >+ up_write(¤t->mm->mmap_sem); >+ if (BAD_ADDR(load_addr_random)) >+ continue; >+ } else >+#endif >+ { >+ error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags); >+ if (BAD_ADDR(error)) >+ continue; >+ } > > if (!load_addr_set) { > load_addr_set = 1; >@@ -687,6 +831,11 @@ > ELF_PAGESTART(load_bias + vaddr); > load_addr += load_bias; > } >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ current->mm->delta_exec = load_addr_random - load_addr; >+#endif >+ > } > k = elf_ppnt->p_vaddr; > if (k < start_code) start_code = k; >@@ -713,6 +862,18 @@ > start_data += load_bias; > end_data += load_bias; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ elf_brk += pax_delta_mask(get_random_long(), 4, PAGE_SHIFT); >+#undef pax_delta_mask >+#endif >+ >+ /* Calling set_brk effectively mmaps the pages that we need >+ * for the bss and break sections >+ */ >+ set_brk(elf_bss, elf_brk); >+ >+ padzero(elf_bss); >+ > if (elf_interpreter) { > if (interpreter_type == INTERPRETER_AOUT) > elf_entry = load_aout_interp(&interp_ex, >@@ -760,13 +921,6 @@ > current->mm->end_data = end_data; > current->mm->start_stack = bprm->p; > >- /* Calling set_brk effectively mmaps the pages that we need >- * for the bss and break sections >- */ >- set_brk(elf_bss, elf_brk); >- >- padzero(elf_bss); >- > #if 0 > printk("(start_brk) %lx\n" , (long) current->mm->start_brk); > printk("(end_code) %lx\n" , (long) current->mm->end_code); >@@ -799,6 +953,10 @@ > ELF_PLAT_INIT(regs); > #endif > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ pax_switch_segments(current); >+#endif >+ > start_thread(regs, elf_entry, bprm->p); > if (current->ptrace & PT_PTRACED) > send_sig(SIGTRAP, current, 0); >@@ -1026,8 +1184,11 @@ > #undef DUMP_SEEK > > #define DUMP_WRITE(addr, nr) \ >+ do { \ >+ gr_learn_resource(current, RLIMIT_CORE, size + (nr)); \ > if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ >- goto end_coredump; >+ goto end_coredump; \ >+ } while (0); > #define DUMP_SEEK(off) \ > if (!dump_seek(file, (off))) \ > goto end_coredump; >diff -Naur linux-2.4.22-ppc-dev.orig/fs/buffer.c linux-2.4.22-ppc-dev/fs/buffer.c >--- linux-2.4.22-ppc-dev.orig/fs/buffer.c 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/buffer.c 2003-09-14 14:07:41.000000000 +0200 >@@ -1826,6 +1826,9 @@ > int err; > > err = -EFBIG; >+ >+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size); >+ > limit = current->rlim[RLIMIT_FSIZE].rlim_cur; > if (limit != RLIM_INFINITY && size > (loff_t)limit) { > send_sig(SIGXFSZ, current, 0); >diff -Naur linux-2.4.22-ppc-dev.orig/fs/exec.c linux-2.4.22-ppc-dev/fs/exec.c >--- linux-2.4.22-ppc-dev.orig/fs/exec.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/exec.c 2003-09-14 14:07:41.000000000 +0200 >@@ -43,6 +43,9 @@ > #include <asm/uaccess.h> > #include <asm/pgalloc.h> > #include <asm/mmu_context.h> >+#include <linux/major.h> >+#include <linux/random.h> >+#include <linux/grsecurity.h> > > #ifdef CONFIG_KMOD > #include <linux/kmod.h> >@@ -345,6 +348,11 @@ > mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p; > mpnt->vm_end = STACK_TOP; > mpnt->vm_flags = VM_STACK_FLAGS; >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (!(current->flags & PF_PAX_PAGEEXEC)) >+ mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7]; >+ else >+#endif > mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7]; > mpnt->vm_ops = NULL; > mpnt->vm_pgoff = 0; >@@ -610,6 +618,30 @@ > } > current->comm[i] = '\0'; > >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ current->flags &= ~PF_PAX_PAGEEXEC; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ current->flags &= ~PF_PAX_EMUTRAMP; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+ current->flags &= ~PF_PAX_MPROTECT; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+ current->flags &= ~PF_PAX_RANDMMAP; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ current->flags &= ~PF_PAX_RANDEXEC; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ current->flags &= ~PF_PAX_SEGMEXEC; >+#endif >+ > flush_thread(); > > de_thread(current); >@@ -709,6 +741,9 @@ > cap_set_full(bprm->cap_effective); > } > >+ if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt)) >+ return -EACCES; >+ > memset(bprm->buf,0,BINPRM_BUF_SIZE); > return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE); > } >@@ -774,6 +809,8 @@ > current->suid = current->euid = current->fsuid = bprm->e_uid; > current->sgid = current->egid = current->fsgid = bprm->e_gid; > >+ gr_handle_chroot_caps(current); >+ > if(do_unlock) > unlock_kernel(); > current->keep_capabilities = 0; >@@ -907,6 +944,11 @@ > struct file *file; > int retval; > int i; >+#ifdef CONFIG_GRKERNSEC >+ struct file *old_exec_file; >+ struct acl_subject_label *old_acl; >+ struct rlimit old_rlim[RLIM_NLIMITS]; >+#endif > > file = open_exec(filename); > >@@ -914,7 +956,26 @@ > if (IS_ERR(file)) > return retval; > >+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes)); >+ >+ if (gr_handle_nproc()) { >+ allow_write_access(file); >+ fput(file); >+ return -EAGAIN; >+ } >+ >+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) { >+ allow_write_access(file); >+ fput(file); >+ return -EACCES; >+ } >+ > bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK >+ bprm.p -= (get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK; >+#endif >+ > memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); > > bprm.file = file; >@@ -938,11 +999,26 @@ > if (retval < 0) > goto out; > >+ if (!gr_tpe_allow(file)) { >+ retval = -EACCES; >+ goto out; >+ } >+ >+ if(gr_check_crash_exec(file)) { >+ retval = -EACCES; >+ goto out; >+ } >+ > retval = copy_strings_kernel(1, &bprm.filename, &bprm); > if (retval < 0) > goto out; > > bprm.exec = bprm.p; >+ >+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); >+ >+ gr_handle_exec_args(&bprm, argv); >+ > retval = copy_strings(bprm.envc, envp, &bprm); > if (retval < 0) > goto out; >@@ -951,11 +1027,32 @@ > if (retval < 0) > goto out; > >+#ifdef CONFIG_GRKERNSEC >+ old_acl = current->acl; >+ memcpy(old_rlim, current->rlim, sizeof(old_rlim)); >+ old_exec_file = current->exec_file; >+ get_file(file); >+ current->exec_file = file; >+#endif >+ >+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt); >+ > 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 >+ current->acl = old_acl; >+ memcpy(current->rlim, old_rlim, sizeof(old_rlim)); >+ 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); >@@ -1097,6 +1194,43 @@ > *out_ptr = 0; > } > >+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) >+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp) >+{ >+ struct task_struct *tsk = current; >+ struct mm_struct *mm = current->mm; >+ char* buffer = (char*)__get_free_page(GFP_ATOMIC); >+ char* path=NULL; >+ >+ if (buffer) { >+ struct vm_area_struct* vma; >+ >+ down_read(&mm->mmap_sem); >+ vma = mm->mmap; >+ while (vma) { >+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) { >+ break; >+ } >+ vma = vma->vm_next; >+ } >+ if (vma) >+ path = d_path(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt, buffer, PAGE_SIZE); >+ up_read(&mm->mmap_sem); >+ } >+ if (tsk->curr_ip) >+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: terminating task: %s(%s):%d, uid/euid: %u/%u, " >+ "PC: %p, SP: %p\n", NIPQUAD(tsk->curr_ip), path, tsk->comm, tsk->pid, >+ tsk->uid, tsk->euid, pc, sp); >+ else >+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, " >+ "PC: %p, SP: %p\n", path, tsk->comm, tsk->pid, >+ tsk->uid, tsk->euid, pc, sp); >+ if (buffer) free_page((unsigned long)buffer); >+ pax_report_insns(pc); >+ do_coredump(SIGKILL, regs); >+} >+#endif >+ > int do_coredump(long signr, struct pt_regs * regs) > { > struct linux_binfmt * binfmt; >@@ -1112,6 +1246,7 @@ > if (!is_dumpable(current)) > goto fail; > current->mm->dumpable = 0; >+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump); > if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump) > goto fail; > >@@ -1131,7 +1266,7 @@ > goto close_fail; > if (!file->f_op->write) > goto close_fail; >- if (do_truncate(file->f_dentry, 0) != 0) >+ if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0) > goto close_fail; > > retval = binfmt->core_dump(signr, regs, file); >diff -Naur linux-2.4.22-ppc-dev.orig/fs/fcntl.c linux-2.4.22-ppc-dev/fs/fcntl.c >--- linux-2.4.22-ppc-dev.orig/fs/fcntl.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/fcntl.c 2003-09-14 14:07:41.000000000 +0200 >@@ -11,6 +11,7 @@ > #include <linux/smp_lock.h> > #include <linux/slab.h> > #include <linux/iobuf.h> >+#include <linux/grsecurity.h> > > #include <asm/poll.h> > #include <asm/siginfo.h> >@@ -64,6 +65,8 @@ > int error; > int start; > >+ gr_learn_resource(current, RLIMIT_NOFILE, orig_start); >+ > write_lock(&files->file_lock); > > error = -EINVAL; >@@ -86,6 +89,7 @@ > } > > error = -EMFILE; >+ gr_learn_resource(current, RLIMIT_NOFILE, newfd); > if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur) > goto out; > >@@ -141,6 +145,8 @@ > struct file * file, *tofree; > struct files_struct * files = current->files; > >+ gr_learn_resource(current, RLIMIT_NOFILE, newfd); >+ > write_lock(&files->file_lock); > if (!(file = fcheck(oldfd))) > goto out_unlock; >@@ -448,6 +454,10 @@ > match = -p->pgrp; > if (pid != match) > continue; >+ if (gr_check_protected_task(p)) >+ continue; >+ if (gr_pid_is_chrooted(p)) >+ continue; > send_sigio_to_task(p, fown, fd, band); > } > out: >diff -Naur linux-2.4.22-ppc-dev.orig/fs/locks.c linux-2.4.22-ppc-dev/fs/locks.c >--- linux-2.4.22-ppc-dev.orig/fs/locks.c 2003-09-14 14:03:05.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/locks.c 2003-09-14 14:07:41.000000000 +0200 >@@ -138,6 +138,7 @@ > static struct file_lock *locks_alloc_lock(int account) > { > struct file_lock *fl; >+ if(account) gr_learn_resource(current, RLIMIT_LOCKS, current->locks); > if (account && current->locks >= current->rlim[RLIMIT_LOCKS].rlim_cur) > return NULL; > fl = kmem_cache_alloc(filelock_cache, SLAB_KERNEL); >diff -Naur linux-2.4.22-ppc-dev.orig/fs/namei.c linux-2.4.22-ppc-dev/fs/namei.c >--- linux-2.4.22-ppc-dev.orig/fs/namei.c 2003-09-14 14:03:05.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/namei.c 2003-09-14 14:07:41.000000000 +0200 >@@ -22,6 +22,7 @@ > #include <linux/dnotify.h> > #include <linux/smp_lock.h> > #include <linux/personality.h> >+#include <linux/grsecurity.h> > > #include <asm/namei.h> > #include <asm/uaccess.h> >@@ -343,6 +344,13 @@ > current->state = TASK_RUNNING; > schedule(); > } >+ >+ if (gr_handle_follow_link(dentry->d_parent->d_inode, >+ dentry->d_inode, dentry, nd->mnt)) { >+ path_release(nd); >+ return -EACCES; >+ } >+ > current->link_count++; > current->total_link_count++; > UPDATE_ATIME(dentry->d_inode); >@@ -643,6 +651,10 @@ > } > } > return_base: >+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) { >+ path_release(nd); >+ return -ENOENT; >+ } > return 0; > out_dput: > dput(dentry); >@@ -1005,7 +1017,7 @@ > struct dentry *dentry; > struct dentry *dir; > int count = 0; >- >+ > acc_mode = ACC_MODE(flag); > > /* >@@ -1015,7 +1027,19 @@ > error = path_lookup(pathname, lookup_flags(flag), nd); > if (error) > return error; >+ >+ if (gr_handle_rawio(nd->dentry->d_inode)) { >+ error = -EPERM; >+ goto exit; >+ } >+ >+ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) { >+ error = -EACCES; >+ goto exit; >+ } >+ > dentry = nd->dentry; >+ > goto ok; > } > >@@ -1048,8 +1072,17 @@ > > /* Negative dentry, just create the file */ > if (!dentry->d_inode) { >+ if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) { >+ error = -EACCES; >+ up(&dir->d_inode->i_sem); >+ goto exit_dput; >+ } >+ > error = vfs_create(dir->d_inode, dentry, > mode & ~current->fs->umask); >+ if (!error) >+ gr_handle_create(dentry, nd->mnt); >+ > up(&dir->d_inode->i_sem); > dput(nd->dentry); > nd->dentry = dentry; >@@ -1058,12 +1091,35 @@ > /* Don't check for write permission, don't truncate */ > acc_mode = 0; > flag &= ~O_TRUNC; >+ > goto ok; > } > > /* > * It already exists. > */ >+ >+ if (gr_acl_is_enabled() && S_ISBLK(dentry->d_inode->i_mode) && >+ !capable(CAP_SYS_RAWIO)) { >+ error = -EPERM; >+ up(&dir->d_inode->i_sem); >+ goto exit_dput; >+ } >+ >+ if (!gr_acl_handle_open(dentry, nd->mnt, flag)) { >+ error = -EACCES; >+ up(&dir->d_inode->i_sem); >+ goto exit_dput; >+ } >+ >+ inode = dentry->d_inode; >+ >+ if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) { >+ up(&dir->d_inode->i_sem); >+ error = -EACCES; >+ goto exit_dput; >+ } >+ > up(&dir->d_inode->i_sem); > > error = -EEXIST; >@@ -1153,7 +1209,7 @@ > if (!error) { > DQUOT_INIT(inode); > >- error = do_truncate(dentry, 0); >+ error = do_truncate(dentry,0,nd->mnt); > } > put_write_access(inode); > if (error) >@@ -1184,6 +1240,13 @@ > * stored in nd->last.name and we will have to putname() it when we > * are done. Procfs-like symlinks just set LAST_BIND. > */ >+ >+ if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode, >+ dentry, nd->mnt)) { >+ error = -EACCES; >+ goto exit_dput; >+ } >+ > UPDATE_ATIME(dentry->d_inode); > error = dentry->d_inode->i_op->follow_link(dentry, nd); > dput(dentry); >@@ -1282,6 +1345,18 @@ > > mode &= ~current->fs->umask; > if (!IS_ERR(dentry)) { >+ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) { >+ error = -EPERM; >+ dput(dentry); >+ goto out_dput; >+ } >+ >+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) { >+ error = -EACCES; >+ dput(dentry); >+ goto out_dput; >+ } >+ > switch (mode & S_IFMT) { > case 0: case S_IFREG: > error = vfs_create(nd.dentry->d_inode,dentry,mode); >@@ -1295,8 +1370,13 @@ > default: > error = -EINVAL; > } >+ >+ if(!error) >+ gr_handle_create(dentry, nd.mnt); >+ > dput(dentry); > } >+out_dput: > up(&nd.dentry->d_inode->i_sem); > path_release(&nd); > out: >@@ -1348,8 +1428,17 @@ > dentry = lookup_create(&nd, 1); > error = PTR_ERR(dentry); > if (!IS_ERR(dentry)) { >- error = vfs_mkdir(nd.dentry->d_inode, dentry, >+ error = 0; >+ >+ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) >+ error = -EACCES; >+ >+ if(!error) >+ error = vfs_mkdir(nd.dentry->d_inode, dentry, > mode & ~current->fs->umask); >+ if(!error) >+ gr_handle_create(dentry, nd.mnt); >+ > dput(dentry); > } > up(&nd.dentry->d_inode->i_sem); >@@ -1433,6 +1522,8 @@ > char * name; > struct dentry *dentry; > struct nameidata nd; >+ ino_t saved_ino = 0; >+ kdev_t saved_dev = 0; > > name = getname(pathname); > if(IS_ERR(name)) >@@ -1457,7 +1548,22 @@ > dentry = lookup_hash(&nd.last, nd.dentry); > error = PTR_ERR(dentry); > if (!IS_ERR(dentry)) { >- error = vfs_rmdir(nd.dentry->d_inode, dentry); >+ error = 0; >+ if (dentry->d_inode) { >+ if (dentry->d_inode->i_nlink <= 1) { >+ saved_ino = dentry->d_inode->i_ino; >+ saved_dev = dentry->d_inode->i_dev; >+ } >+ >+ if (!gr_acl_handle_rmdir(dentry, nd.mnt)) >+ error = -EACCES; >+ } >+ >+ if (!error) >+ error = vfs_rmdir(nd.dentry->d_inode, dentry); >+ if (!error && (saved_dev || saved_ino)) >+ gr_handle_delete(saved_ino,saved_dev); >+ > dput(dentry); > } > up(&nd.dentry->d_inode->i_sem); >@@ -1501,6 +1607,8 @@ > char * name; > struct dentry *dentry; > struct nameidata nd; >+ ino_t saved_ino = 0; >+ kdev_t saved_dev = 0; > > name = getname(pathname); > if(IS_ERR(name)) >@@ -1519,7 +1627,21 @@ > /* Why not before? Because we want correct error value */ > if (nd.last.name[nd.last.len]) > goto slashes; >- error = vfs_unlink(nd.dentry->d_inode, dentry); >+ error = 0; >+ if (dentry->d_inode) { >+ if (dentry->d_inode->i_nlink <= 1) { >+ saved_ino = dentry->d_inode->i_ino; >+ saved_dev = dentry->d_inode->i_dev; >+ } >+ >+ if (!gr_acl_handle_unlink(dentry, nd.mnt)) >+ error = -EACCES; >+ } >+ >+ if (!error) >+ error = vfs_unlink(nd.dentry->d_inode, dentry); >+ if (!error && (saved_ino || saved_dev)) >+ gr_handle_delete(saved_ino,saved_dev); > exit2: > dput(dentry); > } >@@ -1583,7 +1705,15 @@ > dentry = lookup_create(&nd, 0); > error = PTR_ERR(dentry); > if (!IS_ERR(dentry)) { >- error = vfs_symlink(nd.dentry->d_inode, dentry, from); >+ error = 0; >+ >+ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) >+ error = -EACCES; >+ >+ if(!error) >+ error = vfs_symlink(nd.dentry->d_inode, dentry, from); >+ if (!error) >+ gr_handle_create(dentry, nd.mnt); > dput(dentry); > } > up(&nd.dentry->d_inode->i_sem); >@@ -1667,7 +1797,27 @@ > new_dentry = lookup_create(&nd, 0); > error = PTR_ERR(new_dentry); > if (!IS_ERR(new_dentry)) { >- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); >+ error = 0; >+ >+ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt, >+ old_nd.dentry->d_inode, >+ old_nd.dentry->d_inode->i_mode, to)) { >+ error = -EPERM; >+ goto out_error; >+ } >+ >+ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt, >+ old_nd.dentry, old_nd.mnt, to)) { >+ error = -EACCES; >+ goto out_error; >+ } >+ >+ error = vfs_link(old_nd.dentry, >+ nd.dentry->d_inode, new_dentry); >+ >+ if (!error) >+ gr_handle_create(new_dentry, nd.mnt); >+out_error: > dput(new_dentry); > } > up(&nd.dentry->d_inode->i_sem); >@@ -1898,10 +2048,15 @@ > if (IS_ERR(new_dentry)) > goto exit4; > >- lock_kernel(); >- error = vfs_rename(old_dir->d_inode, old_dentry, >+ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt, >+ old_dentry, old_dir->d_inode, oldnd.mnt, newname); >+ >+ if (error == 1) { >+ lock_kernel(); >+ error = vfs_rename(old_dir->d_inode, old_dentry, > new_dir->d_inode, new_dentry); >- unlock_kernel(); >+ unlock_kernel(); >+ } > > dput(new_dentry); > exit4: >diff -Naur linux-2.4.22-ppc-dev.orig/fs/namespace.c linux-2.4.22-ppc-dev/fs/namespace.c >--- linux-2.4.22-ppc-dev.orig/fs/namespace.c 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/namespace.c 2003-09-14 14:07:41.000000000 +0200 >@@ -15,6 +15,8 @@ > #include <linux/quotaops.h> > #include <linux/acct.h> > #include <linux/module.h> >+#include <linux/sched.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > >@@ -325,6 +327,8 @@ > lock_kernel(); > retval = do_remount_sb(sb, MS_RDONLY, 0); > unlock_kernel(); >+ >+ gr_log_remount(mnt->mnt_devname, retval); > } > up_write(&sb->s_umount); > return retval; >@@ -350,6 +354,9 @@ > } > spin_unlock(&dcache_lock); > up_write(¤t->namespace->sem); >+ >+ gr_log_unmount(mnt->mnt_devname, retval); >+ > return retval; > } > >@@ -729,6 +736,12 @@ > if (retval) > return retval; > >+ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) { >+ retval = -EPERM; >+ path_release(&nd); >+ return retval; >+ } >+ > if (flags & MS_REMOUNT) > retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, > data_page); >@@ -740,6 +753,9 @@ > retval = do_add_mount(&nd, type_page, flags, mnt_flags, > dev_name, data_page); > path_release(&nd); >+ >+ gr_log_mount(dev_name, dir_name, retval); >+ > return retval; > } > >@@ -909,6 +925,9 @@ > if (!capable(CAP_SYS_ADMIN)) > return -EPERM; > >+ if (gr_handle_chroot_pivot()) >+ return -EPERM; >+ > lock_kernel(); > > error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd); >diff -Naur linux-2.4.22-ppc-dev.orig/fs/open.c linux-2.4.22-ppc-dev/fs/open.c >--- linux-2.4.22-ppc-dev.orig/fs/open.c 2003-09-14 14:03:05.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/open.c 2003-09-14 14:07:41.000000000 +0200 >@@ -15,6 +15,7 @@ > #include <linux/slab.h> > #include <linux/tty.h> > #include <linux/iobuf.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > >@@ -95,7 +96,7 @@ > write_unlock(&files->file_lock); > } > >-int do_truncate(struct dentry *dentry, loff_t length) >+int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt) > { > struct inode *inode = dentry->d_inode; > int error; >@@ -105,6 +106,9 @@ > if (length < 0) > return -EINVAL; > >+ if (!gr_acl_handle_truncate(dentry, mnt)) >+ return -EACCES; >+ > down_write(&inode->i_alloc_sem); > down(&inode->i_sem); > newattrs.ia_size = length; >@@ -165,7 +169,7 @@ > error = locks_verify_truncate(inode, NULL, length); > if (!error) { > DQUOT_INIT(inode); >- error = do_truncate(nd.dentry, length); >+ error = do_truncate(nd.dentry, length, nd.mnt); > } > put_write_access(inode); > >@@ -217,7 +221,7 @@ > > error = locks_verify_truncate(inode, file, length); > if (!error) >- error = do_truncate(dentry, length); >+ error = do_truncate(dentry, length, file->f_vfsmnt); > out_putf: > fput(file); > out: >@@ -286,6 +290,12 @@ > (error = permission(inode,MAY_WRITE)) != 0) > goto dput_and_out; > } >+ >+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) { >+ error = -EACCES; >+ goto dput_and_out; >+ } >+ > error = notify_change(nd.dentry, &newattrs); > dput_and_out: > path_release(&nd); >@@ -331,6 +341,12 @@ > (error = permission(inode,MAY_WRITE)) != 0) > goto dput_and_out; > } >+ >+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) { >+ error = -EACCES; >+ goto dput_and_out; >+ } >+ > error = notify_change(nd.dentry, &newattrs); > dput_and_out: > path_release(&nd); >@@ -373,6 +389,10 @@ > if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) > && !special_file(nd.dentry->d_inode->i_mode)) > res = -EROFS; >+ >+ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode)) >+ res = -EACCES; >+ > path_release(&nd); > } > >@@ -396,6 +416,8 @@ > if (error) > goto dput_and_out; > >+ gr_log_chdir(nd.dentry, nd.mnt); >+ > set_fs_pwd(current->fs, nd.mnt, nd.dentry); > > dput_and_out: >@@ -426,6 +448,13 @@ > goto out_putf; > > error = permission(inode, MAY_EXEC); >+ >+ if (!error && !gr_chroot_fchdir(dentry, mnt)) >+ error = -EPERM; >+ >+ if (!error) >+ gr_log_chdir(dentry, mnt); >+ > if (!error) > set_fs_pwd(current->fs, mnt, dentry); > out_putf: >@@ -452,8 +481,16 @@ > if (!capable(CAP_SYS_CHROOT)) > goto dput_and_out; > >+ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt)) >+ goto dput_and_out; >+ > set_fs_root(current->fs, nd.mnt, nd.dentry); > set_fs_altroot(); >+ >+ gr_handle_chroot_caps(current); >+ >+ gr_handle_chroot_chdir(nd.dentry, nd.mnt); >+ > error = 0; > dput_and_out: > path_release(&nd); >@@ -482,8 +519,20 @@ > err = -EPERM; > if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) > goto out_putf; >+ >+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) { >+ err = -EACCES; >+ goto out_putf; >+ } >+ > if (mode == (mode_t) -1) > mode = inode->i_mode; >+ >+ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) { >+ err = -EPERM; >+ goto out_putf; >+ } >+ > newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); > newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; > err = notify_change(dentry, &newattrs); >@@ -514,8 +563,19 @@ > if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) > goto dput_and_out; > >+ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) { >+ error = -EACCES; >+ goto dput_and_out; >+ } >+ > if (mode == (mode_t) -1) > mode = inode->i_mode; >+ >+ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) { >+ error = -EACCES; >+ goto dput_and_out; >+ } >+ > newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); > newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; > error = notify_change(nd.dentry, &newattrs); >@@ -526,7 +586,7 @@ > return error; > } > >-static int chown_common(struct dentry * dentry, uid_t user, gid_t group) >+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt) > { > struct inode * inode; > int error; >@@ -543,6 +603,12 @@ > error = -EPERM; > if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) > goto out; >+ >+ if (!gr_acl_handle_chown(dentry, mnt)) { >+ error = -EACCES; >+ goto out; >+ } >+ > if (user == (uid_t) -1) > user = inode->i_uid; > if (group == (gid_t) -1) >@@ -593,7 +659,7 @@ > > error = user_path_walk(filename, &nd); > if (!error) { >- error = chown_common(nd.dentry, user, group); >+ error = chown_common(nd.dentry, user, group, nd.mnt); > path_release(&nd); > } > return error; >@@ -606,7 +672,7 @@ > > error = user_path_walk_link(filename, &nd); > if (!error) { >- error = chown_common(nd.dentry, user, group); >+ error = chown_common(nd.dentry, user, group, nd.mnt); > path_release(&nd); > } > return error; >@@ -620,7 +686,8 @@ > > file = fget(fd); > if (file) { >- error = chown_common(file->f_dentry, user, group); >+ error = chown_common(file->f_dentry, user, >+ group, file->f_vfsmnt); > fput(file); > } > return error; >@@ -740,6 +807,7 @@ > * N.B. For clone tasks sharing a files structure, this test > * will limit the total number of files that can be opened. > */ >+ gr_learn_resource(current, RLIMIT_NOFILE, fd); > if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur) > goto out; > >diff -Naur linux-2.4.22-ppc-dev.orig/fs/proc/array.c linux-2.4.22-ppc-dev/fs/proc/array.c >--- linux-2.4.22-ppc-dev.orig/fs/proc/array.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/proc/array.c 2003-09-14 14:07:41.000000000 +0200 >@@ -297,6 +297,12 @@ > return buffer - orig; > } > >+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP >+#define PAX_RAND_FLAGS (task->flags & PF_PAX_RANDMMAP || \ >+ task->flags & PF_PAX_SEGMEXEC || \ >+ task->flags & PF_PAX_RANDEXEC) >+#endif >+ > int proc_pid_stat(struct task_struct *task, char * buffer) > { > unsigned long vsize, eip, esp, wchan; >@@ -334,6 +340,19 @@ > > wchan = get_wchan(task); > >+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP >+ if (PAX_RAND_FLAGS) { >+ eip = 0; >+ esp = 0; >+ wchan = 0; >+ } >+#endif >+#ifdef CONFIG_GRKERNSEC_HIDESYM >+ wchan = 0; >+ eip = 0; >+ esp = 0; >+#endif >+ > collect_sigign_sigcatch(task, &sigign, &sigcatch); > > /* scale priority and nice values from timeslices to -20..20 */ >@@ -373,9 +392,15 @@ > vsize, > mm ? mm->rss : 0, /* you might want to shift this left 3 */ > task->rlim[RLIMIT_RSS].rlim_cur, >+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP >+ PAX_RAND_FLAGS ? 0 : (mm ? mm->start_code : 0), >+ PAX_RAND_FLAGS ? 0 : (mm ? mm->end_code : 0), >+ PAX_RAND_FLAGS ? 0 : (mm ? mm->start_stack : 0), >+#else > mm ? mm->start_code : 0, > mm ? mm->end_code : 0, > mm ? mm->start_stack : 0, >+#endif > esp, > eip, > /* The signal information here is obsolete. >@@ -541,7 +566,12 @@ > #define MAPS_LINE_FORMAT (sizeof(void*) == 4 ? MAPS_LINE_FORMAT4 : MAPS_LINE_FORMAT8) > #define MAPS_LINE_MAX (sizeof(void*) == 4 ? MAPS_LINE_MAX4 : MAPS_LINE_MAX8) > >+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP >+static int proc_pid_maps_get_line (char *buf, struct vm_area_struct *map, >+ struct task_struct *task) >+#else > static int proc_pid_maps_get_line (char *buf, struct vm_area_struct *map) >+#endif > { > /* produce the next line */ > char *line; >@@ -576,6 +606,16 @@ > } else > line = buf; > >+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP >+ if (task->flags & PF_PAX_RANDMMAP || >+ task->flags & PF_PAX_SEGMEXEC || >+ task->flags & PF_PAX_RANDEXEC) >+ len = sprintf(line, >+ MAPS_LINE_FORMAT, >+ 0UL, 0UL, str, 0UL, >+ kdevname(dev), ino); >+ else >+#endif > len = sprintf(line, > MAPS_LINE_FORMAT, > map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT, >@@ -641,7 +681,11 @@ > off -= PAGE_SIZE; > goto next; > } >+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP >+ len = proc_pid_maps_get_line(tmp, map, task); >+#else > len = proc_pid_maps_get_line(tmp, map); >+#endif > if (len < 0) > goto out_unlock; > len -= off; >@@ -684,6 +728,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 -Naur linux-2.4.22-ppc-dev.orig/fs/proc/base.c linux-2.4.22-ppc-dev/fs/proc/base.c >--- linux-2.4.22-ppc-dev.orig/fs/proc/base.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/proc/base.c 2003-09-14 14:07:41.000000000 +0200 >@@ -25,6 +25,7 @@ > #include <linux/string.h> > #include <linux/seq_file.h> > #include <linux/namespace.h> >+#include <linux/grsecurity.h> > > /* > * 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) > { >@@ -264,9 +268,22 @@ > > static int proc_permission(struct inode *inode, int mask) > { >+ int ret; >+ struct task_struct *task; >+ > if (vfs_permission(inode, mask) != 0) > return -EACCES; >- return proc_check_root(inode); >+ ret = proc_check_root(inode); >+ >+ if (ret) >+ return ret; >+ >+ task = inode->u.proc_i.task; >+ >+ if (!task) >+ return 0; >+ >+ return gr_acl_handle_procpidmem(task); > } > > static ssize_t pid_maps_read(struct file * file, char * buf, >@@ -576,6 +593,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 +611,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), >@@ -747,10 +770,17 @@ > get_task_struct(task); > inode->u.proc_i.task = task; > inode->i_uid = 0; >+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP >+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; >+#else > inode->i_gid = 0; >+#endif >+ > if (ino == PROC_PID_INO || task_dumpable(task)) { > inode->i_uid = task->euid; >+#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP > inode->i_gid = task->egid; >+#endif > } > > out: >@@ -958,6 +988,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; >@@ -1056,13 +1092,34 @@ > if (!task) > goto out; > >+ if(gr_check_hidden_task(task)) { >+ free_task_struct(task); >+ goto out; >+ } >+ >+#ifdef CONFIG_GRKERNSEC_PROC >+ if (current->uid && (task->uid != current->uid) >+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP >+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID) >+#endif >+ ) { >+ free_task_struct(task); >+ goto out; >+ } >+#endif > inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO); > > free_task_struct(task); > > if (!inode) > goto out; >+#ifdef CONFIG_GRKERNSEC_PROC_USER >+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR; >+#elif CONFIG_GRKERNSEC_PROC_USERGROUP >+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP; >+#else > inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; >+#endif > inode->i_op = &proc_base_inode_operations; > inode->i_fop = &proc_base_operations; > inode->i_nlink = 3; >@@ -1102,6 +1159,18 @@ > int pid = p->pid; > if (!pid) > continue; >+ if(gr_pid_is_chrooted(p)) >+ continue; >+ if(gr_check_hidden_task(p)) >+ continue; >+#ifdef CONFIG_GRKERNSEC_PROC >+ if (current->uid && (p->uid != current->uid) >+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP >+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID) >+#endif >+ ) >+ continue; >+#endif > if (--index >= 0) > continue; > pids[nr_pids] = pid; >diff -Naur linux-2.4.22-ppc-dev.orig/fs/proc/generic.c linux-2.4.22-ppc-dev/fs/proc/generic.c >--- linux-2.4.22-ppc-dev.orig/fs/proc/generic.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/proc/generic.c 2003-09-14 14:07:41.000000000 +0200 >@@ -503,6 +503,32 @@ > return ent; > } > >+#ifdef CONFIG_GRKERNSEC_PROC >+struct proc_dir_entry *proc_priv_mkdir(const char *name, struct proc_dir_entry *parent) >+{ >+ struct proc_dir_entry *ent; >+ mode_t mode = 0; >+ >+#ifdef CONFIG_GRKERNSEC_PROC_USER >+ mode = S_IFDIR | S_IRUSR | S_IXUSR; >+#elif CONFIG_GRKERNSEC_PROC_USERGROUP >+ mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP; >+#endif >+ >+ ent = proc_create(&parent, name, mode, 2); >+ if (ent) { >+ ent->proc_fops = &proc_dir_operations; >+ ent->proc_iops = &proc_dir_inode_operations; >+ >+ if (proc_register(parent, ent) < 0) { >+ kfree(ent); >+ ent = NULL; >+ } >+ } >+ return ent; >+} >+#endif >+ > struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, > struct proc_dir_entry *parent) > { >diff -Naur linux-2.4.22-ppc-dev.orig/fs/proc/inode.c linux-2.4.22-ppc-dev/fs/proc/inode.c >--- linux-2.4.22-ppc-dev.orig/fs/proc/inode.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/proc/inode.c 2003-09-14 14:07:41.000000000 +0200 >@@ -152,7 +152,11 @@ > if (de->mode) { > inode->i_mode = de->mode; > inode->i_uid = de->uid; >+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP >+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID; >+#else > inode->i_gid = de->gid; >+#endif > } > if (de->size) > inode->i_size = de->size; >diff -Naur linux-2.4.22-ppc-dev.orig/fs/proc/proc_misc.c linux-2.4.22-ppc-dev/fs/proc/proc_misc.c >--- linux-2.4.22-ppc-dev.orig/fs/proc/proc_misc.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/proc/proc_misc.c 2003-09-14 14:07:41.000000000 +0200 >@@ -569,6 +569,7 @@ > void __init proc_misc_init(void) > { > struct proc_dir_entry *entry; >+ int gr_mode = 0; > static struct { > char *name; > int (*read_proc)(char*,char**,off_t,int,int*,void*); >@@ -583,48 +584,81 @@ > #ifdef CONFIG_STRAM_PROC > {"stram", stram_read_proc}, > #endif >-#ifdef CONFIG_MODULES >+#if defined(CONFIG_MODULES) && !defined(CONFIG_GRKERNSEC_PROC) > {"modules", modules_read_proc}, > #endif > {"stat", kstat_read_proc}, >+#ifndef CONFIG_GRKERNSEC_PROC_ADD > {"devices", devices_read_proc}, >-#if !defined(CONFIG_ARCH_S390) >+#endif >+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_GRKERNSEC_PROC_ADD) > {"interrupts", interrupts_read_proc}, > #endif > {"filesystems", filesystems_read_proc}, >+#ifndef CONFIG_GRKERNSEC_PROC_ADD > {"dma", dma_read_proc}, > {"ioports", ioports_read_proc}, > {"cmdline", cmdline_read_proc}, >+#endif > #ifdef CONFIG_SGI_DS1286 > {"rtc", ds1286_read_proc}, > #endif > {"locks", locks_read_proc}, > {"swaps", swaps_read_proc}, >+#ifndef CONFIG_GRKERNSEC_PROC_ADD > {"iomem", memory_read_proc}, >+#endif > {"execdomains", execdomains_read_proc}, > {NULL,} > }; > for (p = simple_ones; p->name; p++) > create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL); > >+#ifdef CONFIG_GRKERNSEC_PROC_USER >+ gr_mode = S_IRUSR; >+#elif CONFIG_GRKERNSEC_PROC_USERGROUP >+ gr_mode = S_IRUSR | S_IRGRP; >+#endif >+ >+#if defined(CONFIG_GRKERNSEC_PROC) && defined(CONFIG_MODULES) >+ create_proc_read_entry("modules", gr_mode, NULL, &modules_read_proc, NULL); >+#endif >+#ifdef CONFIG_GRKERNSEC_PROC_ADD >+ create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL); >+ create_proc_read_entry("dma", gr_mode, NULL, &dma_read_proc, NULL); >+ create_proc_read_entry("ioports", gr_mode, NULL, &ioports_read_proc, NULL); >+ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL); >+ create_proc_read_entry("iomem", gr_mode, NULL, &memory_read_proc, NULL); >+#if !defined(CONFIG_ARCH_S390) >+ create_proc_read_entry("interrupts", gr_mode, NULL, &interrupts_read_proc, NULL); >+#endif >+#endif >+ > proc_symlink("mounts", NULL, "self/mounts"); > > /* And now for trickier ones */ > entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); > if (entry) > entry->proc_fops = &proc_kmsg_operations; >+#ifdef CONFIG_GRKERNSEC_PROC_ADD >+ create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations); >+ create_seq_entry("slabinfo", gr_mode,&proc_slabinfo_operations); >+#else > create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); >- create_seq_entry("partitions", 0, &proc_partitions_operations); > create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); >+#endif >+ create_seq_entry("partitions", 0, &proc_partitions_operations); > #ifdef CONFIG_MODULES >- create_seq_entry("ksyms", 0, &proc_ksyms_operations); >+ create_seq_entry("ksyms", gr_mode, &proc_ksyms_operations); > #endif >+#ifndef CONFIG_GRKERNSEC_PROC_ADD > proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL); > if (proc_root_kcore) { > proc_root_kcore->proc_fops = &proc_kcore_operations; > proc_root_kcore->size = > (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; > } >+#endif > if (prof_shift) { > entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL); > if (entry) { >diff -Naur linux-2.4.22-ppc-dev.orig/fs/proc/proc_tty.c linux-2.4.22-ppc-dev/fs/proc/proc_tty.c >--- linux-2.4.22-ppc-dev.orig/fs/proc/proc_tty.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/proc/proc_tty.c 2003-09-14 14:07:41.000000000 +0200 >@@ -174,7 +174,11 @@ > if (!proc_mkdir("tty", 0)) > return; > proc_tty_ldisc = proc_mkdir("tty/ldisc", 0); >+#ifdef CONFIG_GRKERNSEC_PROC >+ proc_tty_driver = proc_priv_mkdir("tty/driver", 0); >+#else > proc_tty_driver = proc_mkdir("tty/driver", 0); >+#endif > > create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL); > create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL); >diff -Naur linux-2.4.22-ppc-dev.orig/fs/proc/root.c linux-2.4.22-ppc-dev/fs/proc/root.c >--- linux-2.4.22-ppc-dev.orig/fs/proc/root.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/proc/root.c 2003-09-14 14:07:41.000000000 +0200 >@@ -37,13 +37,21 @@ > return; > } > proc_misc_init(); >+#ifdef CONFIG_GRKERNSEC_PROC >+ proc_net = proc_priv_mkdir("net", 0); >+#else > proc_net = proc_mkdir("net", 0); >+#endif > #ifdef CONFIG_SYSVIPC > proc_mkdir("sysvipc", 0); > #endif > #ifdef CONFIG_SYSCTL >+#ifdef CONFIG_GRKERNSEC_PROC >+ proc_sys_root = proc_priv_mkdir("sys", 0); >+#else > proc_sys_root = proc_mkdir("sys", 0); > #endif >+#endif > #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) > proc_mkdir("sys/fs", 0); > proc_mkdir("sys/fs/binfmt_misc", 0); >@@ -67,7 +75,12 @@ > #ifdef CONFIG_PPC_RTAS > proc_rtas_init(); > #endif >+ >+#ifdef CONFIG_GRKERNSEC_PROC_ADD >+ proc_bus = proc_priv_mkdir("bus", 0); >+#else > proc_bus = proc_mkdir("bus", 0); >+#endif > } > > static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry) >diff -Naur linux-2.4.22-ppc-dev.orig/fs/readdir.c linux-2.4.22-ppc-dev/fs/readdir.c >--- linux-2.4.22-ppc-dev.orig/fs/readdir.c 2003-09-14 14:03:06.000000000 +0200 >+++ linux-2.4.22-ppc-dev/fs/readdir.c 2003-09-14 14:07:41.000000000 +0200 >@@ -10,6 +10,7 @@ > #include <linux/stat.h> > #include <linux/file.h> > #include <linux/smp_lock.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > >@@ -181,6 +182,7 @@ > struct readdir_callback { > struct old_linux_dirent * dirent; > int count; >+ struct nameidata nd; > }; > > static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, >@@ -191,6 +193,10 @@ > > if (buf->count) > return -EINVAL; >+ >+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino)) >+ return 0; >+ > buf->count++; > dirent = buf->dirent; > put_user(ino, &dirent->d_ino); >@@ -215,6 +221,9 @@ > buf.count = 0; > buf.dirent = dirent; > >+ buf.nd.dentry = file->f_dentry; >+ buf.nd.mnt = file->f_vfsmnt; >+ > error = vfs_readdir(file, fillonedir, &buf); > if (error >= 0) > error = buf.count; >@@ -242,6 +251,7 @@ > struct linux_dirent * previous; > int count; > int error; >+ struct nameidata nd; > }; > > static int filldir(void * __buf, const char * name, int namlen, loff_t offset, >@@ -254,6 +264,10 @@ > buf->error = -EINVAL; /* only used if we fail.. */ > if (reclen > buf->count) > return -EINVAL; >+ >+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino)) >+ return 0; >+ > dirent = buf->previous; > if (dirent) > put_user(offset, &dirent->d_off); >@@ -286,6 +300,9 @@ > buf.count = count; > buf.error = 0; > >+ buf.nd.dentry = file->f_dentry; >+ buf.nd.mnt = file->f_vfsmnt; >+ > error = vfs_readdir(file, filldir, &buf); > if (error < 0) > goto out_putf; >@@ -320,6 +337,7 @@ > struct linux_dirent64 * previous; > int count; > int error; >+ struct nameidata nd; > }; > > static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, >@@ -332,6 +350,10 @@ > buf->error = -EINVAL; /* only used if we fail.. */ > if (reclen > buf->count) > return -EINVAL; >+ >+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino)) >+ return 0; >+ > dirent = buf->previous; > if (dirent) { > d.d_off = offset; >@@ -369,6 +391,9 @@ > buf.count = count; > buf.error = 0; > >+ buf.nd.mnt = file->f_vfsmnt; >+ buf.nd.dentry = file->f_dentry; >+ > error = vfs_readdir(file, filldir64, &buf); > if (error < 0) > goto out_putf; >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/Config.in linux-2.4.22-ppc-dev/grsecurity/Config.in >--- linux-2.4.22-ppc-dev.orig/grsecurity/Config.in 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/Config.in 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,366 @@ >+define_bool CONFIG_CRYPTO y >+define_bool CONFIG_CRYPTO_SHA256 y >+choice 'Security level' \ >+ "Low CONFIG_GRKERNSEC_LOW \ >+ Medium CONFIG_GRKERNSEC_MID \ >+ High CONFIG_GRKERNSEC_HI \ >+ Customized CONFIG_GRKERNSEC_CUSTOM" Customized >+if [ "$CONFIG_GRKERNSEC_LOW" = "y" ]; then >+define_bool CONFIG_GRKERNSEC_RANDSRC n >+define_bool CONFIG_GRKERNSEC_RANDRPC n >+define_bool CONFIG_GRKERNSEC_FORKFAIL n >+define_bool CONFIG_GRKERNSEC_TIME n >+define_bool CONFIG_GRKERNSEC_SIGNAL n >+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n >+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT n >+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n >+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE n >+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT n >+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD n >+define_bool CONFIG_GRKERNSEC_PROC n >+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n >+define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n >+define_bool CONFIG_GRKERNSEC_HIDESYM n >+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n >+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL n >+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP n >+define_bool CONFIG_GRKERNSEC_KMEM n >+define_bool CONFIG_GRKERNSEC_PROC_ADD n >+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n >+define_bool CONFIG_GRKERNSEC_CHROOT_NICE n >+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n >+define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK n >+define_bool CONFIG_GRKERNSEC_PAX_ASLR n >+define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP n >+define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n >+define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n >+define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n >+if [ "$CONFIG_X86" = "y" ]; then >+define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n >+define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n >+define_bool CONFIG_GRKERNSEC_IO n >+define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n >+define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n >+fi >+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n >+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n >+define_bool CONFIG_GRKERNSEC_RESLOG n >+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3 >+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30 >+ >+define_int CONFIG_GRKERNSEC_FLOODTIME 10 >+define_int CONFIG_GRKERNSEC_FLOODBURST 4 >+define_bool CONFIG_GRKERNSEC_LINK y >+define_bool CONFIG_GRKERNSEC_FIFO y >+define_bool CONFIG_GRKERNSEC_RANDPID y >+define_bool CONFIG_GRKERNSEC_EXECVE y >+define_bool CONFIG_GRKERNSEC_RANDNET y >+define_bool CONFIG_GRKERNSEC_RANDISN n >+define_bool CONFIG_GRKERNSEC_DMESG y >+define_bool CONFIG_GRKERNSEC_RANDID y >+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y >+fi >+if [ "$CONFIG_GRKERNSEC_MID" = "y" ]; then >+define_bool CONFIG_GRKERNSEC_KMEM n >+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n >+define_bool CONFIG_GRKERNSEC_PROC_MEMMAP n >+define_bool CONFIG_GRKERNSEC_HIDESYM n >+define_bool CONFIG_GRKERNSEC_PROC_ADD n >+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n >+define_bool CONFIG_GRKERNSEC_CHROOT_NICE n >+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n >+define_bool CONFIG_GRKERNSEC_PAX_NOEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n >+define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n >+define_bool CONFIG_GRKERNSEC_PAX_MPROTECT n >+if [ "$CONFIG_X86" = "y" ]; then >+define_bool CONFIG_GRKERNSEC_IO n >+define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n >+define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n >+fi >+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n >+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n >+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y >+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n >+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n >+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n >+define_bool CONFIG_GRKERNSEC_RESLOG n >+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3 >+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30 >+ >+define_int CONFIG_GRKERNSEC_FLOODTIME 10 >+define_int CONFIG_GRKERNSEC_FLOODBURST 4 >+define_bool CONFIG_GRKERNSEC_LINK y >+define_bool CONFIG_GRKERNSEC_FIFO y >+define_bool CONFIG_GRKERNSEC_RANDPID y >+define_bool CONFIG_GRKERNSEC_EXECVE y >+define_bool CONFIG_GRKERNSEC_DMESG y >+define_bool CONFIG_GRKERNSEC_RANDID y >+define_bool CONFIG_GRKERNSEC_RANDNET y >+define_bool CONFIG_GRKERNSEC_RANDISN y >+define_bool CONFIG_GRKERNSEC_RANDSRC y >+define_bool CONFIG_GRKERNSEC_RANDRPC y >+define_bool CONFIG_GRKERNSEC_FORKFAIL y >+define_bool CONFIG_GRKERNSEC_TIME y >+define_bool CONFIG_GRKERNSEC_SIGNAL y >+define_bool CONFIG_GRKERNSEC_CHROOT y >+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n >+define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y >+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y >+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y >+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y >+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y >+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y >+define_bool CONFIG_GRKERNSEC_PROC y >+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y >+define_int CONFIG_GRKERNSEC_PROC_GID 10 >+define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y >+define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK n >+define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_ASLR y >+define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y >+fi >+if [ "$CONFIG_GRKERNSEC_HI" = "y" ]; then >+define_int CONFIG_GRKERNSEC_FLOODTIME 10 >+define_int CONFIG_GRKERNSEC_FLOODBURST 4 >+define_bool CONFIG_GRKERNSEC_LINK y >+define_bool CONFIG_GRKERNSEC_FIFO y >+define_bool CONFIG_GRKERNSEC_RANDPID y >+define_bool CONFIG_GRKERNSEC_EXECVE y >+define_bool CONFIG_GRKERNSEC_DMESG y >+define_bool CONFIG_GRKERNSEC_RANDID y >+define_bool CONFIG_GRKERNSEC_RANDSRC y >+define_bool CONFIG_GRKERNSEC_RANDRPC y >+define_bool CONFIG_GRKERNSEC_FORKFAIL y >+define_bool CONFIG_GRKERNSEC_TIME y >+define_bool CONFIG_GRKERNSEC_SIGNAL y >+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT y >+define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y >+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y >+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR y >+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y >+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y >+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y >+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y >+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS y >+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y >+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK y >+define_bool CONFIG_GRKERNSEC_PROC y >+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n >+define_bool CONFIG_GRKERNSEC_PROC_MEMMAP y >+define_bool CONFIG_GRKERNSEC_HIDESYM y >+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y >+define_int CONFIG_GRKERNSEC_PROC_GID 10 >+define_bool CONFIG_GRKERNSEC_KMEM y >+define_bool CONFIG_GRKERNSEC_RESLOG y >+define_bool CONFIG_GRKERNSEC_RANDNET y >+define_bool CONFIG_GRKERNSEC_RANDISN y >+ >+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n >+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n >+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3 >+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30 >+ >+define_bool CONFIG_GRKERNSEC_PROC_ADD y >+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD y >+define_bool CONFIG_GRKERNSEC_CHROOT_NICE y >+define_bool CONFIG_GRKERNSEC_PAX_RANDUSTACK y >+define_bool CONFIG_GRKERNSEC_PAX_ASLR y >+define_bool CONFIG_GRKERNSEC_PAX_RANDMMAP y >+define_bool CONFIG_GRKERNSEC_PAX_NOEXEC y >+define_bool CONFIG_GRKERNSEC_PAX_PAGEEXEC n >+define_bool CONFIG_GRKERNSEC_PAX_NOELFRELOCS n >+define_bool CONFIG_GRKERNSEC_PAX_MPROTECT y >+define_bool CONFIG_GRKERNSEC_PAX_ETEXECRELOCS n >+if [ "$CONFIG_X86" = "y" ]; then >+define_bool CONFIG_GRKERNSEC_IO n >+if [ "$CONFIG_MODULES" = "n" ]; then >+define_bool CONFIG_GRKERNSEC_PAX_KERNEXEC y >+fi >+define_bool CONFIG_GRKERNSEC_PAX_RANDKSTACK y >+define_bool CONFIG_GRKERNSEC_PAX_RANDEXEC y >+define_bool CONFIG_GRKERNSEC_PAX_SEGMEXEC y >+define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP n >+define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT n >+fi >+if [ "$CONFIG_PARISC" = "y" ]; then >+define_bool CONFIG_GRKERNSEC_PAX_EMUTRAMP y >+define_bool CONFIG_GRKERNSEC_PAX_EMUSIGRT y >+fi >+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT y >+fi >+if [ "$CONFIG_GRKERNSEC_CUSTOM" = "y" ]; then >+mainmenu_option next_comment >+comment 'Address Space Protection' >+bool 'Enforce non-executable pages' CONFIG_GRKERNSEC_PAX_NOEXEC >+if [ "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then >+ bool 'Paging based non-executable pages' CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if [ "$CONFIG_X86" = "y" ]; then >+ bool 'Segmentation based non-executable pages' CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ fi >+ if [ "$CONFIG_X86" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_PPC32" = "y" ]; then >+ if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then >+ bool ' Emulate trampolines' CONFIG_GRKERNSEC_PAX_EMUTRAMP >+ if [ "$CONFIG_GRKERNSEC_PAX_EMUTRAMP" = "y" ]; then >+ bool ' Automatically emulate sigreturn trampolines' CONFIG_GRKERNSEC_PAX_EMUSIGRT >+ fi >+ fi >+ fi >+ bool ' Restrict mprotect()' CONFIG_GRKERNSEC_PAX_MPROTECT >+ if [ "$CONFIG_GRKERNSEC_PAX_MPROTECT" = "y" ]; then >+ if [ "$CONFIG_X86" = "y" ]; then >+ bool ' Disallow ELF text relocations (DANGEROUS)' CONFIG_GRKERNSEC_PAX_NOELFRELOCS >+ else >+ if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" ]; then >+ bool ' Allow ELF ET_EXEC text relocations' CONFIG_GRKERNSEC_PAX_ETEXECRELOCS >+ fi >+ if [ "$CONFIG_PPC32" = "y" ]; then >+ define_bool CONFIG_GRKERNSEC_PAX_SYSCALL y >+ fi >+ if [ "$CONFIG_ALPHA" = "y" -o "$CONFIG_PARISC" = "y" -o "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" -o "$CONFIG_PPC32" = "y" ]; then >+ bool ' Automatically emulate ELF PLT' CONFIG_GRKERNSEC_PAX_EMUPLT >+ if [ "$CONFIG_GRKERNSEC_PAX_EMUPLT" = "y" ]; then >+ if [ "$CONFIG_SPARC32" = "y" -o "$CONFIG_SPARC64" = "y" ]; then >+ define_bool CONFIG_GRKERNSEC_PAX_DLRESOLVE y >+ fi >+ fi >+ fi >+ fi >+ fi >+fi >+if [ "$CONFIG_X86" = "y" -a "$CONFIG_MODULES" = "n" ]; then >+ bool 'Enforce non-executable kernel pages' CONFIG_GRKERNSEC_PAX_KERNEXEC >+fi >+bool 'Address Space Layout Randomization' CONFIG_GRKERNSEC_PAX_ASLR >+if [ "$CONFIG_GRKERNSEC_PAX_ASLR" = "y" ]; then >+ if [ "$CONFIG_X86_TSC" = "y" ]; then >+ bool ' Randomize kernel stack base' CONFIG_GRKERNSEC_PAX_RANDKSTACK >+ fi >+ bool ' Randomize user stack base' CONFIG_GRKERNSEC_PAX_RANDUSTACK >+ bool ' Randomize mmap() base' CONFIG_GRKERNSEC_PAX_RANDMMAP >+ if [ "$CONFIG_GRKERNSEC_PAX_RANDMMAP" = "y" -a "$CONFIG_GRKERNSEC_PAX_NOEXEC" = "y" ]; then >+ if [ "$CONFIG_GRKERNSEC_PAX_PAGEEXEC" = "y" -o "$CONFIG_GRKERNSEC_PAX_SEGMEXEC" = "y" ]; then >+ bool ' Randomize ET_EXEC base' CONFIG_GRKERNSEC_PAX_RANDEXEC >+ fi >+ fi >+fi >+bool 'Deny writing to /dev/kmem, /dev/mem, and /dev/port' CONFIG_GRKERNSEC_KMEM >+if [ "$CONFIG_X86" = "y" ]; then >+ bool 'Disable privileged I/O' CONFIG_GRKERNSEC_IO >+ if [ "$CONFIG_GRKERNSEC_IO" = "y" ]; then >+ define_bool CONFIG_RTC y >+ fi >+fi >+bool 'Remove addresses from /proc/pid/[maps|stat]' CONFIG_GRKERNSEC_PROC_MEMMAP >+bool 'Hide kernel symbols' CONFIG_GRKERNSEC_HIDESYM >+endmenu >+mainmenu_option next_comment >+comment 'Role Based Access Control Options' >+bool 'Hide kernel processes' CONFIG_GRKERNSEC_ACL_HIDEKERN >+int 'Maximum tries before password lockout' CONFIG_GRKERNSEC_ACL_MAXTRIES 3 >+int 'Time to wait after max password tries, in seconds' CONFIG_GRKERNSEC_ACL_TIMEOUT 30 >+endmenu >+mainmenu_option next_comment >+comment 'Filesystem Protections' >+bool 'Proc restrictions' CONFIG_GRKERNSEC_PROC >+if [ "$CONFIG_GRKERNSEC_PROC" != "n" ]; then >+ bool ' Restrict to user only' CONFIG_GRKERNSEC_PROC_USER >+ if [ "$CONFIG_GRKERNSEC_PROC_USER" != "y" ]; then >+ bool ' Allow special group' CONFIG_GRKERNSEC_PROC_USERGROUP >+ if [ "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then >+ int ' GID for special group' CONFIG_GRKERNSEC_PROC_GID 1001 >+ fi >+ fi >+ if [ "$CONFIG_GRKERNSEC_PROC_USER" != "n" -o "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then >+ bool ' Additional restrictions' CONFIG_GRKERNSEC_PROC_ADD >+ fi >+fi >+bool 'Linking restrictions' CONFIG_GRKERNSEC_LINK >+bool 'FIFO restrictions' CONFIG_GRKERNSEC_FIFO >+bool 'Chroot jail restrictions' CONFIG_GRKERNSEC_CHROOT >+if [ "$CONFIG_GRKERNSEC_CHROOT" != "n" ]; then >+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 >+fi >+endmenu >+mainmenu_option next_comment >+comment 'Kernel Auditing' >+bool 'Single group for auditing' CONFIG_GRKERNSEC_AUDIT_GROUP >+if [ "$CONFIG_GRKERNSEC_AUDIT_GROUP" != "n" ]; then >+int ' GID for auditing' CONFIG_GRKERNSEC_AUDIT_GID 1007 >+fi >+bool 'Exec logging' CONFIG_GRKERNSEC_EXECLOG >+bool 'Resource logging' CONFIG_GRKERNSEC_RESLOG >+bool 'Log execs within chroot' CONFIG_GRKERNSEC_CHROOT_EXECLOG >+bool 'Chdir logging' CONFIG_GRKERNSEC_AUDIT_CHDIR >+bool '(Un)Mount logging' CONFIG_GRKERNSEC_AUDIT_MOUNT >+bool 'IPC logging' CONFIG_GRKERNSEC_AUDIT_IPC >+bool 'Signal logging' CONFIG_GRKERNSEC_SIGNAL >+bool 'Fork failure logging' CONFIG_GRKERNSEC_FORKFAIL >+bool 'Time change logging' CONFIG_GRKERNSEC_TIME >+bool '/proc/<pid>/ipaddr support' CONFIG_GRKERNSEC_PROC_IPADDR >+endmenu >+mainmenu_option next_comment >+comment 'Executable Protections' >+bool 'Enforce RLIMIT_NPROC on execs' CONFIG_GRKERNSEC_EXECVE >+bool 'Dmesg(8) restriction' CONFIG_GRKERNSEC_DMESG >+bool 'Randomized PIDs' CONFIG_GRKERNSEC_RANDPID >+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 >+endmenu >+mainmenu_option next_comment >+comment 'Network Protections' >+bool 'Larger entropy pools' CONFIG_GRKERNSEC_RANDNET >+bool 'Truly random TCP ISN selection' CONFIG_GRKERNSEC_RANDISN >+bool 'Randomized IP IDs' CONFIG_GRKERNSEC_RANDID >+bool 'Randomized TCP source ports' CONFIG_GRKERNSEC_RANDSRC >+bool 'Randomized RPC XIDs' CONFIG_GRKERNSEC_RANDRPC >+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 >+endmenu >+if [ "$CONFIG_SYSCTL" != "n" ]; then >+mainmenu_option next_comment >+comment 'Sysctl support' >+bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL >+endmenu >+fi >+mainmenu_option next_comment >+comment 'Logging options' >+int 'Seconds in between log messages (minimum)' CONFIG_GRKERNSEC_FLOODTIME 10 >+int 'Number of messages in a burst (maximum)' CONFIG_GRKERNSEC_FLOODBURST 4 >+endmenu >+fi >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/Makefile linux-2.4.22-ppc-dev/grsecurity/Makefile >--- linux-2.4.22-ppc-dev.orig/grsecurity/Makefile 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/Makefile 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,24 @@ >+# 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-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \ >+ grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \ >+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o >+ >+ifeq ($(CONFIG_GRKERNSEC),y) >+obj-y += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \ >+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \ >+ gracl_learn.o >+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o >+else >+obj-y += grsec_disabled.o >+endif >+ >+include $(TOPDIR)/Rules.make >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl.c linux-2.4.22-ppc-dev/grsecurity/gracl.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl.c 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,2766 @@ >+/* >+ * grsecurity/gracl.c >+ * Copyright Brad Spengler 2001, 2002, 2003 >+ * >+ */ >+ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/mm.h> >+#include <linux/file.h> >+#include <linux/fs.h> >+#include <linux/proc_fs.h> >+#include <linux/smp_lock.h> >+#include <linux/slab.h> >+#include <linux/vmalloc.h> >+#include <linux/types.h> >+#include <linux/capability.h> >+#include <linux/sysctl.h> >+#include <linux/gracl.h> >+#include <linux/gralloc.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+#include <asm/uaccess.h> >+#include <asm/errno.h> >+#include <asm/mman.h> >+ >+static struct acl_role_db acl_role_set; >+static struct acl_role_label *role_list_head; >+static struct name_db name_set; >+static struct name_db inodev_set; >+ >+static struct acl_role_label *default_role; >+ >+static u16 acl_sp_role_value; >+ >+static DECLARE_MUTEX(gr_dev_sem); >+rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED; >+ >+extern char *gr_shared_page[4][NR_CPUS]; >+struct gr_arg *gr_usermode; >+ >+static unsigned long gr_status = GR_STATUS_INIT; >+ >+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum); >+extern void gr_clear_learn_entries(void); >+ >+#ifdef CONFIG_GRKERNSEC_RESLOG >+extern __inline__ void gr_log_resource(const struct task_struct *task, >+ const int res, >+ const unsigned long wanted); >+#endif >+ >+unsigned char *gr_system_salt; >+unsigned char *gr_system_sum; >+ >+static struct sprole_pw **acl_special_roles = NULL; >+static __u16 num_sprole_pws = 0; >+ >+static struct acl_role_label *kernel_role = NULL; >+ >+/* The following are used to keep a place held in the hash table when we move >+ entries around. They can be replaced during insert. */ >+ >+static struct acl_subject_label *deleted_subject; >+static struct acl_object_label *deleted_object; >+static struct name_entry *deleted_inodev; >+ >+/* for keeping track of the last and final allocated subjects, since >+ nested subject parsing is tricky >+*/ >+static struct acl_subject_label *s_last = NULL; >+static struct acl_subject_label *s_final = NULL; >+ >+static unsigned int gr_auth_attempts = 0; >+static unsigned long gr_auth_expires = 0UL; >+ >+extern int gr_init_uidset(void); >+extern void gr_free_uidset(void); >+extern void gr_remove_uid(uid_t uid); >+extern int gr_find_uid(uid_t uid); >+ >+__inline__ int >+gr_acl_is_enabled(void) >+{ >+ return (gr_status & GR_READY); >+} >+ >+__inline__ int >+gr_acl_tpe_check(void) >+{ >+ if (unlikely(!(gr_status & GR_READY))) >+ return 0; >+ if (current->role->roletype & GR_ROLE_TPE) >+ return 1; >+ else >+ return 0; >+} >+ >+int >+gr_handle_rawio(const struct inode *inode) >+{ >+ if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) && >+ ((gr_status & GR_READY) >+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS >+ || (grsec_enable_chroot_caps && proc_is_chrooted(current)) >+#endif >+ )) >+ return 1; >+ return 0; >+} >+ >+ >+static __inline__ int >+gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb) >+{ >+ int i; >+ unsigned long *l1; >+ unsigned long *l2; >+ unsigned char *c1; >+ unsigned char *c2; >+ int num_longs; >+ >+ if (likely(lena != lenb)) >+ return 0; >+ >+ l1 = (unsigned long *)a; >+ l2 = (unsigned long *)b; >+ >+ num_longs = lena / sizeof(unsigned long); >+ >+ for (i = num_longs; i--; l1++, l2++) { >+ if (unlikely(*l1 != *l2)) >+ return 0; >+ } >+ >+ c1 = (unsigned char *) l1; >+ c2 = (unsigned char *) l2; >+ >+ i = lena - (num_longs * sizeof(unsigned long)); >+ >+ for (; i--; c1++, c2++) { >+ if (unlikely(*c1 != *c2)) >+ return 0; >+ } >+ >+ return 1; >+} >+ >+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); >+} >+ >+__inline__ __u32 >+to_gr_audit(const __u32 reqmode) >+{ >+ __u32 retmode = 0; >+ >+ retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0; >+ retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0; >+ retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0; >+ retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0; >+ retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0; >+ retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0; >+ retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0; >+ retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0; >+ retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0; >+ >+ return retmode; >+} >+ >+__inline__ struct acl_role_label * >+lookup_acl_role_label(const struct task_struct *task, const uid_t uid, >+ const gid_t gid) >+{ >+ unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size); >+ struct acl_role_label *match; >+ struct role_allowed_ip *ipp; >+ __u8 i = 0; >+ >+ match = acl_role_set.r_hash[index]; >+ >+ while (match >+ && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) { >+ index = (index + (1 << i)) % acl_role_set.r_size; >+ match = acl_role_set.r_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (!match || match->uidgid != uid || !(match->roletype & GR_ROLE_USER)) { >+ try_group: >+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size); >+ match = acl_role_set.r_hash[index]; >+ i = 0; >+ >+ while (match >+ && (match->uidgid != gid >+ || !(match->roletype & GR_ROLE_GROUP))) { >+ index = (index + (1 << i)) % acl_role_set.r_size; >+ match = acl_role_set.r_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (!match || match->uidgid != gid >+ || !(match->roletype & GR_ROLE_GROUP)) >+ match = default_role; >+ else if (likely(!match->allowed_ips)) { >+ return match; >+ } else { >+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { >+ if (likely >+ ((task->curr_ip & ipp->netmask) == >+ (ipp->addr & ipp->netmask))) >+ return match; >+ } >+ match = default_role; >+ } >+ } else if (likely(!match->allowed_ips)) { >+ return match; >+ } else { >+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) { >+ if (likely >+ ((task->curr_ip & ipp->netmask) == >+ (ipp->addr & ipp->netmask))) >+ return match; >+ } >+ goto try_group; >+ } >+ >+ return match; >+} >+ >+__inline__ struct acl_subject_label * >+lookup_acl_subj_label(const ino_t ino, const kdev_t dev, >+ const struct acl_role_label *role) >+{ >+ unsigned long subj_size = role->subj_hash_size; >+ struct acl_subject_label **s_hash = role->subj_hash; >+ unsigned long index = fhash(ino, dev, subj_size); >+ struct acl_subject_label *match; >+ __u8 i = 0; >+ >+ match = s_hash[index]; >+ >+ while (match && (match->inode != ino || match->device != dev || >+ (match->mode & GR_DELETED))) { >+ index = (index + (1 << i)) % subj_size; >+ match = s_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (unlikely(match && (match != deleted_subject) && >+ (match->inode == ino) && (match->device == dev) && >+ !(match->mode & GR_DELETED))) >+ return match; >+ else >+ return NULL; >+} >+ >+static __inline__ struct acl_object_label * >+lookup_acl_obj_label(const ino_t ino, const kdev_t dev, >+ const struct acl_subject_label *subj) >+{ >+ unsigned long obj_size = subj->obj_hash_size; >+ struct acl_object_label **o_hash = subj->obj_hash; >+ unsigned long index = fhash(ino, dev, obj_size); >+ struct acl_object_label *match; >+ __u8 i = 0; >+ >+ match = o_hash[index]; >+ >+ while (match && (match->inode != ino || match->device != dev || >+ (match->mode & GR_DELETED))) { >+ index = (index + (1 << i)) % obj_size; >+ match = o_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (unlikely(match && (match != deleted_object) && >+ (match->inode == ino) && (match->device == dev) && >+ !(match->mode & GR_DELETED))) >+ return match; >+ else >+ return NULL; >+} >+ >+static __inline__ struct acl_object_label * >+lookup_acl_obj_label_create(const ino_t ino, const kdev_t dev, >+ const struct acl_subject_label *subj) >+{ >+ unsigned long obj_size = subj->obj_hash_size; >+ struct acl_object_label **o_hash = subj->obj_hash; >+ unsigned long index = fhash(ino, dev, obj_size); >+ struct acl_object_label *match; >+ __u8 i = 0; >+ >+ match = o_hash[index]; >+ >+ while (match && (match->inode != ino || match->device != dev || >+ !(match->mode & GR_DELETED))) { >+ index = (index + (1 << i)) % obj_size; >+ match = o_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (unlikely(match && (match != deleted_object) && >+ (match->inode == ino) && (match->device == dev) && >+ (match->mode & GR_DELETED))) >+ return match; >+ >+ i = 0; >+ index = fhash(ino, dev, obj_size); >+ match = o_hash[index]; >+ >+ while (match && (match->inode != ino || match->device != dev || >+ (match->mode & GR_DELETED))) { >+ index = (index + (1 << i)) % obj_size; >+ match = o_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (unlikely(match && (match != deleted_object) && >+ (match->inode == ino) && (match->device == dev) && >+ !(match->mode & GR_DELETED))) >+ return match; >+ else >+ return NULL; >+} >+ >+static __inline__ struct name_entry * >+lookup_name_entry(const char *name) >+{ >+ __u16 len = strlen(name); >+ unsigned long index = nhash(name, len, name_set.n_size); >+ struct name_entry *match; >+ __u8 i = 0; >+ >+ match = name_set.n_hash[index]; >+ >+ while (match && !gr_streq(match->name, name, match->len, len)) { >+ index = (index + (1 << i)) % name_set.n_size; >+ match = name_set.n_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (unlikely(!match || !gr_streq(match->name, name, match->len, len))) >+ return NULL; >+ else >+ return match; >+} >+ >+static __inline__ struct name_entry * >+lookup_inodev_entry(const ino_t ino, const kdev_t dev) >+{ >+ unsigned long index = fhash(ino, dev, inodev_set.n_size); >+ struct name_entry *match; >+ __u8 i = 0; >+ >+ match = inodev_set.n_hash[index]; >+ >+ while (match && (match->inode != ino || match->device != dev)) { >+ index = (index + (1 << i)) % inodev_set.n_size; >+ match = inodev_set.n_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (unlikely(match && (match != deleted_inodev) && >+ (match->inode == ino) && (match->device == dev))) >+ return match; >+ else >+ return NULL; >+} >+ >+static void >+insert_inodev_entry(struct name_entry *nentry) >+{ >+ unsigned long index = fhash(nentry->inode, nentry->device, >+ inodev_set.n_size); >+ struct name_entry **curr; >+ __u8 i = 0; >+ >+ curr = &inodev_set.n_hash[index]; >+ >+ while (*curr && *curr != deleted_inodev) { >+ index = (index + (1 << i)) % inodev_set.n_size; >+ curr = &inodev_set.n_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ *curr = nentry; >+ >+ return; >+} >+ >+static void >+insert_acl_role_label(struct acl_role_label *role) >+{ >+ unsigned long index = >+ rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size); >+ struct acl_role_label **curr; >+ __u8 i = 0; >+ >+ curr = &acl_role_set.r_hash[index]; >+ >+ while (*curr) { >+ index = (index + (1 << i)) % acl_role_set.r_size; >+ curr = &acl_role_set.r_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ *curr = role; >+ >+ return; >+} >+ >+static int >+insert_name_entry(char *name, const ino_t inode, const kdev_t device) >+{ >+ struct name_entry **curr; >+ __u8 i = 0; >+ __u16 len = strlen(name); >+ unsigned long index = nhash(name, len, name_set.n_size); >+ >+ curr = &name_set.n_hash[index]; >+ >+ while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) { >+ index = (index + (1 << i)) % name_set.n_size; >+ curr = &name_set.n_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (!(*curr)) { >+ struct name_entry *nentry = >+ acl_alloc(sizeof (struct name_entry)); >+ if (!nentry) >+ return 0; >+ nentry->name = name; >+ nentry->inode = inode; >+ nentry->device = device; >+ nentry->len = len; >+ *curr = nentry; >+ /* insert us into the table searchable by inode/dev */ >+ insert_inodev_entry(nentry); >+ } >+ >+ return 1; >+} >+ >+static void >+insert_acl_obj_label(struct acl_object_label *obj, >+ struct acl_subject_label *subj) >+{ >+ unsigned long index = >+ fhash(obj->inode, obj->device, subj->obj_hash_size); >+ struct acl_object_label **curr; >+ __u8 i = 0; >+ >+ curr = &subj->obj_hash[index]; >+ >+ while (*curr && *curr != deleted_object) { >+ index = (index + (1 << i)) % subj->obj_hash_size; >+ curr = &subj->obj_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ *curr = obj; >+ >+ return; >+} >+ >+static void >+insert_acl_subj_label(struct acl_subject_label *obj, >+ struct acl_role_label *role) >+{ >+ unsigned long subj_size = role->subj_hash_size; >+ struct acl_subject_label **s_hash = role->subj_hash; >+ unsigned long index = fhash(obj->inode, obj->device, subj_size); >+ struct acl_subject_label **curr; >+ __u8 i = 0; >+ >+ curr = &s_hash[index]; >+ >+ while (*curr && *curr != deleted_subject) { >+ index = (index + (1 << i)) % subj_size; >+ curr = &s_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ *curr = obj; >+ >+ return; >+} >+ >+static void ** >+create_table(__u32 * len) >+{ >+ unsigned long table_sizes[] = { >+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, >+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143, >+ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689, >+ 268435399, 536870909, 1073741789, 2147483647 >+ }; >+ void *newtable = NULL; >+ unsigned int pwr = 0; >+ >+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) && >+ table_sizes[pwr] <= (2 * (*len))) >+ pwr++; >+ >+ if (table_sizes[pwr] <= (2 * (*len))) >+ return newtable; >+ >+ if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE) >+ newtable = >+ kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL); >+ else >+ newtable = vmalloc(table_sizes[pwr] * sizeof (void *)); >+ >+ *len = table_sizes[pwr]; >+ >+ return newtable; >+} >+ >+static int >+init_variables(const unsigned long acl_obj_size, >+ const unsigned long acl_subj_size, >+ const unsigned long acl_ip_size, >+ const unsigned long acl_role_size, >+ const unsigned long allowed_ip_size, >+ const unsigned long acl_trans_size, >+ const __u16 num_sprole_pws) >+{ >+ unsigned long stacksize; >+ >+ acl_role_set.r_size = acl_role_size; >+ name_set.n_size = (acl_obj_size + acl_subj_size); >+ inodev_set.n_size = (acl_obj_size + acl_subj_size); >+ >+ if (!gr_init_uidset()) >+ return 1; >+ >+ /* set up the stack that holds allocation info */ >+ >+ stacksize = (3 * acl_obj_size) + (2 * acl_role_size) + >+ (4 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) + >+ allowed_ip_size + (2 * num_sprole_pws) + 5; >+ >+ if (!acl_alloc_stack_init(stacksize)) >+ return 1; >+ >+ /* create our empty, fake deleted acls */ >+ deleted_subject = >+ (struct acl_subject_label *) >+ acl_alloc(sizeof (struct acl_subject_label)); >+ deleted_object = >+ (struct acl_object_label *) >+ acl_alloc(sizeof (struct acl_object_label)); >+ deleted_inodev = >+ (struct name_entry *) acl_alloc(sizeof (struct name_entry)); >+ >+ if (!deleted_subject || !deleted_object || !deleted_inodev) >+ return 1; >+ >+ memset(deleted_subject, 0, sizeof (struct acl_subject_label)); >+ memset(deleted_object, 0, sizeof (struct acl_object_label)); >+ memset(deleted_inodev, 0, sizeof (struct name_entry)); >+ >+ /* We only want 50% full tables for now */ >+ >+ acl_role_set.r_hash = >+ (struct acl_role_label **) create_table(&acl_role_set.r_size); >+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size); >+ inodev_set.n_hash = >+ (struct name_entry **) create_table(&inodev_set.n_size); >+ >+ if (!acl_role_set.r_hash || !name_set.n_hash || !inodev_set.n_hash) >+ return 1; >+ memset(acl_role_set.r_hash, 0, >+ sizeof (struct acl_role_label *) * acl_role_set.r_size); >+ memset(name_set.n_hash, 0, >+ sizeof (struct name_entry *) * name_set.n_size); >+ memset(inodev_set.n_hash, 0, >+ sizeof (struct name_entry *) * inodev_set.n_size); >+ >+ return 0; >+} >+ >+static void >+free_variables(void) >+{ >+ struct acl_subject_label *s; >+ struct acl_role_label *r; >+ struct task_struct *task; >+ >+ gr_clear_learn_entries(); >+ >+ read_lock(&tasklist_lock); >+ for_each_task(task) { >+ task->acl_sp_role = 0; >+ task->acl_role_id = 0; >+ task->acl = NULL; >+ task->role = NULL; >+ } >+ read_unlock(&tasklist_lock); >+ >+ /* free all object hash tables */ >+ >+ if (role_list_head) { >+ for (r = role_list_head; r; r = r->next) { >+ if (!r->subj_hash) >+ break; >+ for (s = r->proc_subject; s; s = s->next) { >+ if (!s->obj_hash) >+ break; >+ if ((s->obj_hash_size * >+ sizeof (struct acl_object_label *)) <= >+ PAGE_SIZE) >+ kfree(s->obj_hash); >+ else >+ vfree(s->obj_hash); >+ } >+ if ((r->subj_hash_size * >+ sizeof (struct acl_subject_label *)) <= PAGE_SIZE) >+ kfree(r->subj_hash); >+ else >+ vfree(r->subj_hash); >+ } >+ } >+ >+ acl_free_all(); >+ >+ if (acl_role_set.r_hash) { >+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <= >+ PAGE_SIZE) >+ kfree(acl_role_set.r_hash); >+ else >+ vfree(acl_role_set.r_hash); >+ } >+ if (name_set.n_hash) { >+ if ((name_set.n_size * sizeof (struct name_entry *)) <= >+ PAGE_SIZE) >+ kfree(name_set.n_hash); >+ else >+ vfree(name_set.n_hash); >+ } >+ >+ if (inodev_set.n_hash) { >+ if ((inodev_set.n_size * sizeof (struct name_entry *)) <= >+ PAGE_SIZE) >+ kfree(inodev_set.n_hash); >+ else >+ vfree(inodev_set.n_hash); >+ } >+ >+ gr_free_uidset(); >+ >+ memset(&name_set, 0, sizeof (struct name_db)); >+ memset(&inodev_set, 0, sizeof (struct name_db)); >+ memset(&acl_role_set, 0, sizeof (struct acl_role_db)); >+ >+ role_list_head = NULL; >+ default_role = NULL; >+ >+ return; >+} >+ >+static __u32 >+count_user_objs(struct acl_object_label *userp) >+{ >+ struct acl_object_label o_tmp; >+ __u32 num = 0; >+ >+ while (userp) { >+ if (copy_from_user(&o_tmp, userp, >+ sizeof (struct acl_object_label))) >+ break; >+ >+ userp = o_tmp.prev; >+ num++; >+ } >+ >+ return num; >+} >+ >+static struct acl_subject_label * >+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role); >+ >+static int >+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj, >+ struct acl_role_label *role) >+{ >+ struct acl_object_label *o_tmp; >+ unsigned int len; >+ char *tmp; >+ >+ while (userp) { >+ if ((o_tmp = (struct acl_object_label *) >+ acl_alloc(sizeof (struct acl_object_label))) == NULL) >+ return -ENOMEM; >+ >+ if (copy_from_user(o_tmp, userp, >+ sizeof (struct acl_object_label))) >+ return -EFAULT; >+ >+ userp = o_tmp->prev; >+ >+ len = strnlen_user(o_tmp->filename, PATH_MAX); >+ >+ if (!len || len >= PATH_MAX) >+ return -EINVAL; >+ >+ if ((tmp = (char *) acl_alloc(len)) == NULL) >+ return -ENOMEM; >+ >+ if (copy_from_user(tmp, o_tmp->filename, len)) >+ return -EFAULT; >+ >+ o_tmp->filename = tmp; >+ >+ insert_acl_obj_label(o_tmp, subj); >+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode, >+ o_tmp->device)) >+ return -ENOMEM; >+ >+ if (o_tmp->nested) { >+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role); >+ if (IS_ERR(o_tmp->nested)) >+ return PTR_ERR(o_tmp->nested); >+ >+ s_final = o_tmp->nested; >+ } >+ } >+ >+ return 0; >+} >+ >+static __u32 >+count_user_subjs(struct acl_subject_label *userp) >+{ >+ struct acl_subject_label s_tmp; >+ __u32 num = 0; >+ >+ while (userp) { >+ if (copy_from_user(&s_tmp, userp, >+ sizeof (struct acl_subject_label))) >+ break; >+ >+ userp = s_tmp.prev; >+ /* do not count nested subjects against this count, since >+ they are not included in the hash table, but are >+ attached to objects. We have already counted >+ the subjects in userspace for the allocation >+ stack >+ */ >+ if (!s_tmp.parent_subject) >+ num++; >+ } >+ >+ return num; >+} >+ >+static int >+copy_user_allowedips(struct acl_role_label *rolep) >+{ >+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast; >+ >+ ruserip = rolep->allowed_ips; >+ >+ while (ruserip) { >+ rlast = rtmp; >+ >+ if ((rtmp = (struct role_allowed_ip *) >+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL) >+ return -ENOMEM; >+ >+ if (copy_from_user(rtmp, ruserip, >+ sizeof (struct role_allowed_ip))) >+ return -EFAULT; >+ >+ ruserip = rtmp->prev; >+ >+ if (!rlast) { >+ rtmp->prev = NULL; >+ rolep->allowed_ips = rtmp; >+ } else { >+ rlast->next = rtmp; >+ rtmp->prev = rlast; >+ } >+ >+ if (!ruserip) >+ rtmp->next = NULL; >+ } >+ >+ return 0; >+} >+ >+static int >+copy_user_transitions(struct acl_role_label *rolep) >+{ >+ struct role_transition *rusertp, *rtmp = NULL, *rlast; >+ unsigned int len; >+ char *tmp; >+ >+ rusertp = rolep->transitions; >+ >+ while (rusertp) { >+ rlast = rtmp; >+ >+ if ((rtmp = (struct role_transition *) >+ acl_alloc(sizeof (struct role_transition))) == NULL) >+ return -ENOMEM; >+ >+ if (copy_from_user(rtmp, rusertp, >+ sizeof (struct role_transition))) >+ return -EFAULT; >+ >+ rusertp = rtmp->prev; >+ >+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN); >+ >+ if (!len || len >= GR_SPROLE_LEN) >+ return -EINVAL; >+ >+ if ((tmp = (char *) acl_alloc(len)) == NULL) >+ return -ENOMEM; >+ >+ if (copy_from_user(tmp, rtmp->rolename, len)) >+ return -EFAULT; >+ >+ rtmp->rolename = tmp; >+ >+ if (!rlast) { >+ rtmp->prev = NULL; >+ rolep->transitions = rtmp; >+ } else { >+ rlast->next = rtmp; >+ rtmp->prev = rlast; >+ } >+ >+ if (!rusertp) >+ rtmp->next = NULL; >+ } >+ >+ return 0; >+} >+ >+static struct acl_subject_label * >+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role) >+{ >+ struct acl_subject_label *s_tmp = NULL; >+ unsigned int len; >+ char *tmp; >+ __u32 num_objs; >+ struct acl_ip_label **i_tmp, *i_utmp2; >+ unsigned long i_num; >+ int err; >+ >+ >+ if ((s_tmp = (struct acl_subject_label *) >+ acl_alloc(sizeof (struct acl_subject_label))) == NULL) >+ return ERR_PTR(-ENOMEM); >+ >+ if (copy_from_user(s_tmp, userp, >+ sizeof (struct acl_subject_label))) >+ return ERR_PTR(-EFAULT); >+ >+ if (!s_last) { >+ s_tmp->prev = NULL; >+ role->proc_subject = s_tmp; >+ } else { >+ s_last->next = s_tmp; >+ s_tmp->prev = s_last; >+ } >+ >+ s_last = s_tmp; >+ >+ len = strnlen_user(s_tmp->filename, PATH_MAX); >+ >+ if (!len || len >= PATH_MAX) >+ return ERR_PTR(-EINVAL); >+ >+ if ((tmp = (char *) acl_alloc(len)) == NULL) >+ return ERR_PTR(-ENOMEM); >+ >+ if (copy_from_user(tmp, s_tmp->filename, len)) >+ return ERR_PTR(-EFAULT); >+ >+ s_tmp->filename = tmp; >+ >+ if (!strcmp(s_tmp->filename, "/")) >+ role->root_label = s_tmp; >+ >+ /* set up object hash table */ >+ num_objs = count_user_objs(s_tmp->proc_object); >+ >+ s_tmp->obj_hash_size = num_objs; >+ s_tmp->obj_hash = >+ (struct acl_object_label **) >+ create_table(&(s_tmp->obj_hash_size)); >+ >+ if (!s_tmp->obj_hash) >+ return ERR_PTR(-ENOMEM); >+ >+ memset(s_tmp->obj_hash, 0, >+ s_tmp->obj_hash_size * >+ sizeof (struct acl_object_label *)); >+ >+ /* copy before adding in objects, since a nested >+ acl could be found and be the final subject >+ copied >+ */ >+ >+ s_final = s_tmp; >+ >+ /* add in objects */ >+ err = copy_user_objs(s_tmp->proc_object, s_tmp, role); >+ >+ if (err) >+ return ERR_PTR(err); >+ >+ /* add in ip acls */ >+ >+ if (!s_tmp->ip_num) { >+ s_tmp->ips = NULL; >+ goto insert; >+ } >+ >+ i_tmp = >+ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num * >+ sizeof (struct >+ acl_ip_label *)); >+ >+ if (!i_tmp) >+ return ERR_PTR(-ENOMEM); >+ >+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) { >+ *(i_tmp + i_num) = >+ (struct acl_ip_label *) >+ acl_alloc(sizeof (struct acl_ip_label)); >+ if (!*(i_tmp + i_num)) >+ return ERR_PTR(-ENOMEM); >+ >+ if (copy_from_user >+ (&i_utmp2, s_tmp->ips + i_num, >+ sizeof (struct acl_ip_label *))) >+ return ERR_PTR(-EFAULT); >+ >+ if (copy_from_user >+ (*(i_tmp + i_num), i_utmp2, >+ sizeof (struct acl_ip_label))) >+ return ERR_PTR(-EFAULT); >+ } >+ >+ s_tmp->ips = i_tmp; >+ >+insert: >+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode, >+ s_tmp->device)) >+ return ERR_PTR(-ENOMEM); >+ >+ return s_tmp; >+} >+ >+static int >+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role) >+{ >+ struct acl_subject_label s_pre; >+ struct acl_subject_label * ret; >+ int err; >+ >+ while (userp) { >+ if (copy_from_user(&s_pre, userp, >+ sizeof (struct acl_subject_label))) >+ return -EFAULT; >+ >+ /* do not add nested subjects here, add >+ while parsing objects >+ */ >+ >+ if (s_pre.parent_subject) { >+ userp = s_pre.prev; >+ continue; >+ } >+ >+ ret = do_copy_user_subj(userp, role); >+ >+ err = PTR_ERR(ret); >+ if (IS_ERR(ret)) >+ return err; >+ >+ insert_acl_subj_label(ret, role); >+ >+ userp = s_pre.prev; >+ } >+ >+ s_final->next = NULL; >+ >+ return 0; >+} >+ >+static int >+copy_user_acl(struct gr_arg *arg) >+{ >+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last; >+ struct sprole_pw *sptmp; >+ unsigned long r_num; >+ unsigned int len; >+ char *tmp; >+ int err = 0; >+ __u16 i; >+ __u32 num_subjs; >+ >+ /* we need a default and kernel role */ >+ if (arg->role_db.r_entries < 2) >+ return -EINVAL; >+ >+ /* copy special role authentication info from userspace */ >+ >+ num_sprole_pws = arg->num_sprole_pws; >+ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *)); >+ >+ if (!acl_special_roles) { >+ err = -ENOMEM; >+ goto cleanup; >+ } >+ >+ for (i = 0; i < num_sprole_pws; i++) { >+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw)); >+ if (!sptmp) { >+ err = -ENOMEM; >+ goto cleanup; >+ } >+ if (copy_from_user(sptmp, arg->sprole_pws + i, >+ sizeof (struct sprole_pw))) { >+ err = -EFAULT; >+ goto cleanup; >+ } >+ >+ len = >+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN); >+ >+ if (!len || len >= GR_SPROLE_LEN) { >+ err = -EINVAL; >+ goto cleanup; >+ } >+ >+ if ((tmp = (char *) acl_alloc(len)) == NULL) { >+ err = -ENOMEM; >+ goto cleanup; >+ } >+ >+ if (copy_from_user(tmp, sptmp->rolename, len)) { >+ err = -EFAULT; >+ goto cleanup; >+ } >+ >+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG >+ printk(KERN_ALERT "Copying special role %s\n", tmp); >+#endif >+ sptmp->rolename = tmp; >+ acl_special_roles[i] = sptmp; >+ } >+ >+ r_utmp = (struct acl_role_label **) arg->role_db.r_table; >+ >+ for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) { >+ r_last = r_tmp; >+ >+ r_tmp = acl_alloc(sizeof (struct acl_role_label)); >+ >+ if (!r_tmp) { >+ err = -ENOMEM; >+ goto cleanup; >+ } >+ >+ if (copy_from_user(&r_utmp2, r_utmp + r_num, >+ sizeof (struct acl_role_label *))) { >+ err = -EFAULT; >+ goto cleanup; >+ } >+ >+ if (copy_from_user(r_tmp, r_utmp2, >+ sizeof (struct acl_role_label))) { >+ err = -EFAULT; >+ goto cleanup; >+ } >+ >+ if (!r_last) { >+ r_tmp->prev = NULL; >+ role_list_head = r_tmp; >+ } else { >+ r_last->next = r_tmp; >+ r_tmp->prev = r_last; >+ } >+ >+ if (r_num == (arg->role_db.r_entries - 1)) >+ r_tmp->next = NULL; >+ >+ len = strnlen_user(r_tmp->rolename, PATH_MAX); >+ >+ if (!len || len >= PATH_MAX) { >+ err = -EINVAL; >+ goto cleanup; >+ } >+ >+ if ((tmp = (char *) acl_alloc(len)) == NULL) { >+ err = -ENOMEM; >+ goto cleanup; >+ } >+ if (copy_from_user(tmp, r_tmp->rolename, len)) { >+ err = -EFAULT; >+ goto cleanup; >+ } >+ r_tmp->rolename = tmp; >+ >+ if (!strcmp(r_tmp->rolename, "default") >+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) { >+ default_role = r_tmp; >+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) { >+ kernel_role = r_tmp; >+ } >+ >+ num_subjs = count_user_subjs(r_tmp->proc_subject); >+ >+ r_tmp->subj_hash_size = num_subjs; >+ r_tmp->subj_hash = >+ (struct acl_subject_label **) >+ create_table(&(r_tmp->subj_hash_size)); >+ >+ if (!r_tmp->subj_hash) { >+ err = -ENOMEM; >+ goto cleanup; >+ } >+ >+ err = copy_user_allowedips(r_tmp); >+ if (err) >+ goto cleanup; >+ >+ err = copy_user_transitions(r_tmp); >+ if (err) >+ goto cleanup; >+ >+ memset(r_tmp->subj_hash, 0, >+ r_tmp->subj_hash_size * >+ sizeof (struct acl_subject_label *)); >+ >+ s_last = NULL; >+ >+ err = copy_user_subjs(r_tmp->proc_subject, r_tmp); >+ >+ if (err) >+ goto cleanup; >+ >+ insert_acl_role_label(r_tmp); >+ } >+ >+ goto return_err; >+ cleanup: >+ free_variables(); >+ return_err: >+ return err; >+ >+} >+ >+static int >+gracl_init(struct gr_arg *args) >+{ >+ int error = 0; >+ >+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN); >+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN); >+ >+ if (init_variables(args->role_db.o_entries, args->role_db.s_entries, >+ args->role_db.i_entries, args->role_db.r_entries, >+ args->role_db.a_entries, args->role_db.t_entries, >+ args->num_sprole_pws)) { >+ security_alert_good(GR_INITF_ACL_MSG, GR_VERSION); >+ error = -ENOMEM; >+ free_variables(); >+ goto out; >+ } >+ >+ error = copy_user_acl(args); >+ if (error) >+ goto out; >+ >+ if ((error = gr_set_acls(0))) { >+ free_variables(); >+ goto out; >+ } >+ >+ gr_status |= GR_READY; >+ out: >+ return error; >+} >+ >+static struct acl_object_label * >+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, >+ const struct acl_subject_label *subj) >+{ >+ struct dentry *dentry = (struct dentry *) l_dentry; >+ struct vfsmount *mnt = (struct vfsmount *) l_mnt; >+ struct dentry *root; >+ struct vfsmount *rootmnt; >+ struct acl_object_label *retval; >+ >+ 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); >+ >+ for (;;) { >+ if (unlikely(dentry == root && mnt == rootmnt)) >+ break; >+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) { >+ if (mnt->mnt_parent == mnt) >+ break; >+ >+ read_lock(&gr_inode_lock); >+ retval = >+ lookup_acl_obj_label(dentry->d_inode->i_ino, >+ dentry->d_inode->i_dev, subj); >+ read_unlock(&gr_inode_lock); >+ if (unlikely(retval != NULL)) >+ goto out; >+ >+ dentry = mnt->mnt_mountpoint; >+ mnt = mnt->mnt_parent; >+ continue; >+ } >+ >+ read_lock(&gr_inode_lock); >+ retval = >+ lookup_acl_obj_label(dentry->d_inode->i_ino, >+ dentry->d_inode->i_dev, subj); >+ read_unlock(&gr_inode_lock); >+ if (unlikely(retval != NULL)) >+ goto out; >+ >+ dentry = dentry->d_parent; >+ } >+ >+ read_lock(&gr_inode_lock); >+ retval = >+ lookup_acl_obj_label(dentry->d_inode->i_ino, dentry->d_inode->i_dev, >+ subj); >+ read_unlock(&gr_inode_lock); >+ >+ if (unlikely(retval == NULL)) { >+ read_lock(&gr_inode_lock); >+ retval = >+ lookup_acl_obj_label(root->d_inode->i_ino, >+ root->d_inode->i_dev, subj); >+ read_unlock(&gr_inode_lock); >+ } >+ out: >+ spin_unlock(&dcache_lock); >+ dput(root); >+ mntput(rootmnt); >+ >+ return retval; >+} >+ >+static struct acl_subject_label * >+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt, >+ const struct acl_role_label *role) >+{ >+ struct dentry *dentry = (struct dentry *) l_dentry; >+ struct vfsmount *mnt = (struct vfsmount *) l_mnt; >+ struct dentry *root; >+ struct vfsmount *rootmnt; >+ struct acl_subject_label *retval; >+ >+ 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); >+ >+ for (;;) { >+ if (unlikely(dentry == root && mnt == rootmnt)) >+ break; >+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) { >+ if (mnt->mnt_parent == mnt) >+ break; >+ >+ read_lock(&gr_inode_lock); >+ retval = >+ lookup_acl_subj_label(dentry->d_inode->i_ino, >+ dentry->d_inode->i_dev, role); >+ read_unlock(&gr_inode_lock); >+ if (unlikely(retval != NULL)) >+ goto out; >+ >+ dentry = mnt->mnt_mountpoint; >+ mnt = mnt->mnt_parent; >+ continue; >+ } >+ >+ read_lock(&gr_inode_lock); >+ retval = >+ lookup_acl_subj_label(dentry->d_inode->i_ino, >+ dentry->d_inode->i_dev, role); >+ read_unlock(&gr_inode_lock); >+ if (unlikely(retval != NULL)) >+ goto out; >+ >+ dentry = dentry->d_parent; >+ } >+ >+ read_lock(&gr_inode_lock); >+ retval = >+ lookup_acl_subj_label(dentry->d_inode->i_ino, >+ dentry->d_inode->i_dev, role); >+ read_unlock(&gr_inode_lock); >+ >+ if (unlikely(retval == NULL)) { >+ read_lock(&gr_inode_lock); >+ retval = >+ lookup_acl_subj_label(root->d_inode->i_ino, >+ root->d_inode->i_dev, role); >+ read_unlock(&gr_inode_lock); >+ } >+ out: >+ spin_unlock(&dcache_lock); >+ dput(root); >+ mntput(rootmnt); >+ >+ return retval; >+} >+ >+static __inline__ void >+gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid, >+ const struct task_struct *task, const char *pathname, >+ const __u32 mode) >+{ >+ security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype, >+ uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry, >+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename, >+ 1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip)); >+ >+ return; >+} >+ >+__u32 >+gr_check_link(const struct dentry * new_dentry, >+ const struct dentry * parent_dentry, >+ const struct vfsmount * parent_mnt, >+ const struct dentry * old_dentry, const struct vfsmount * old_mnt) >+{ >+ struct acl_object_label *obj; >+ __u32 oldmode, newmode; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return (GR_WRITE | GR_CREATE); >+ >+ obj = chk_obj_label(old_dentry, old_mnt, current->acl); >+ oldmode = obj->mode; >+ >+ if (current->acl->mode & GR_LEARN) >+ oldmode |= (GR_WRITE | GR_CREATE); >+ newmode = >+ gr_check_create(new_dentry, parent_dentry, parent_mnt, >+ oldmode | GR_CREATE | GR_AUDIT_CREATE | >+ GR_AUDIT_WRITE | GR_SUPPRESS); >+ >+ if ((newmode & oldmode) == oldmode) >+ return newmode; >+ else if (current->acl->mode & GR_LEARN) { >+ gr_log_learn(current->role, current->uid, current->gid, >+ current, gr_to_filename(old_dentry, old_mnt), oldmode); >+ return (GR_WRITE | GR_CREATE); >+ } else if (newmode & GR_SUPPRESS) >+ return GR_SUPPRESS; >+ else >+ return 0; >+} >+ >+__u32 >+gr_search_file(const struct dentry * dentry, const __u32 mode, >+ const struct vfsmount * mnt) >+{ >+ __u32 retval = mode; >+ struct acl_subject_label *curracl; >+ struct acl_object_label *currobj; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return (mode & ~GR_AUDITS); >+ >+ curracl = current->acl; >+ >+ currobj = chk_obj_label(dentry, mnt, curracl); >+ retval = currobj->mode & mode; >+ >+ if (unlikely >+ ((curracl->mode & GR_LEARN) && (mode != GR_PTRACERD) >+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) { >+ __u32 new_mode = mode; >+ >+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); >+ >+ retval = new_mode; >+ >+ if (!(mode & GR_NOLEARN)) >+ gr_log_learn(current->role, current->uid, current->gid, >+ current, gr_to_filename(dentry, mnt), new_mode); >+ } >+ >+ return retval; >+} >+ >+__u32 >+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent, >+ const struct vfsmount * mnt, const __u32 mode) >+{ >+ struct name_entry *match; >+ struct acl_object_label *matchpo; >+ struct acl_subject_label *curracl; >+ __u32 retval; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return (mode & ~GR_AUDITS); >+ >+ match = lookup_name_entry(gr_to_filename(new_dentry, mnt)); >+ >+ if (!match) >+ goto check_parent; >+ >+ curracl = current->acl; >+ >+ read_lock(&gr_inode_lock); >+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl); >+ read_unlock(&gr_inode_lock); >+ >+ if (matchpo) { >+ if ((matchpo->mode & mode) != >+ (mode & ~(GR_AUDITS | GR_SUPPRESS)) >+ && curracl->mode & GR_LEARN) { >+ __u32 new_mode = mode; >+ >+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); >+ >+ gr_log_learn(current->role, current->uid, current->gid, >+ current, gr_to_filename(new_dentry, mnt), new_mode); >+ >+ return new_mode; >+ } >+ return (matchpo->mode & mode); >+ } >+ >+ check_parent: >+ curracl = current->acl; >+ >+ matchpo = chk_obj_label(parent, mnt, curracl); >+ retval = matchpo->mode & mode; >+ >+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))) >+ && (curracl->mode & GR_LEARN)) { >+ __u32 new_mode = mode; >+ >+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); >+ >+ gr_log_learn(current->role, current->uid, current->gid, >+ current, gr_to_filename(new_dentry, mnt), new_mode); >+ return new_mode; >+ } >+ >+ return retval; >+} >+ >+int >+gr_check_hidden_task(const struct task_struct *task) >+{ >+ if (unlikely(!(gr_status & GR_READY))) >+ return 0; >+ >+ if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW)) >+ return 1; >+ >+ return 0; >+} >+ >+int >+gr_check_protected_task(const struct task_struct *task) >+{ >+ if (unlikely(!(gr_status & GR_READY) || !task)) >+ return 0; >+ >+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL)) >+ return 1; >+ >+ return 0; >+} >+ >+__inline__ void >+gr_copy_label(struct task_struct *tsk) >+{ >+ tsk->used_accept = 0; >+ tsk->used_connect = 0; >+ tsk->acl_sp_role = 0; >+ tsk->acl_role_id = current->acl_role_id; >+ tsk->acl = current->acl; >+ tsk->role = current->role; >+ tsk->curr_ip = current->curr_ip; >+ if (current->exec_file) >+ get_file(current->exec_file); >+ tsk->exec_file = current->exec_file; >+ tsk->is_writable = current->is_writable; >+ if (unlikely(current->used_accept)) >+ current->curr_ip = 0; >+ >+ return; >+} >+ >+static __inline__ void >+gr_set_proc_res(void) >+{ >+ struct acl_subject_label *proc; >+ unsigned short i; >+ >+ proc = current->acl; >+ >+ if (proc->mode & GR_LEARN) >+ return; >+ >+ for (i = 0; i < RLIM_NLIMITS; i++) { >+ if (!(proc->resmask & (1 << i))) >+ continue; >+ >+ current->rlim[i].rlim_cur = proc->res[i].rlim_cur; >+ current->rlim[i].rlim_max = proc->res[i].rlim_max; >+ } >+ >+ return; >+} >+ >+void >+gr_set_pax_flags(struct task_struct *task) >+{ >+ struct acl_subject_label *proc; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return; >+ >+ proc = task->acl; >+ >+ if (proc->mode & GR_PAXPAGE) >+ task->flags &= ~PF_PAX_PAGEEXEC; >+ if (proc->mode & GR_PAXSEGM) >+ task->flags &= ~PF_PAX_SEGMEXEC; >+ if (proc->mode & GR_PAXGCC) >+ task->flags |= PF_PAX_EMUTRAMP; >+ if (proc->mode & GR_PAXMPROTECT) >+ task->flags &= ~PF_PAX_MPROTECT; >+ if (proc->mode & GR_PAXRANDMMAP) >+ task->flags &= ~PF_PAX_RANDMMAP; >+ if (proc->mode & GR_PAXRANDEXEC) >+ task->flags |= PF_PAX_RANDEXEC; >+ >+ return; >+} >+ >+static __inline__ void >+do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid) >+{ >+ task->role = lookup_acl_role_label(task, uid, gid); >+ >+ return; >+} >+ >+void >+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid) >+{ >+ struct acl_object_label *obj; >+ struct file *filp; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return; >+ >+ filp = task->exec_file; >+ >+ /* kernel process, we'll give them the kernel role */ >+ if (unlikely(!filp)) { >+ task->role = kernel_role; >+ task->acl = kernel_role->root_label; >+ return; >+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL)) >+ do_set_role_label(task, uid, gid); >+ >+ task->acl = >+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role); >+ >+ task->is_writable = 0; >+ >+ /* ignore additional mmap checks for processes that are writable >+ by the default ACL */ >+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); >+ if (unlikely(obj->mode & GR_WRITE)) >+ task->is_writable = 1; >+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label); >+ if (unlikely(obj->mode & GR_WRITE)) >+ task->is_writable = 1; >+ >+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG >+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); >+#endif >+ >+ gr_set_proc_res(); >+ >+ return; >+} >+ >+void >+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ struct acl_subject_label *newacl; >+ struct acl_object_label *obj; >+ __u32 retmode; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return; >+ >+ newacl = chk_subj_label(dentry, mnt, current->role); >+ >+ obj = chk_obj_label(dentry, mnt, current->acl); >+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT); >+ >+ if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) { >+ if (obj->nested) >+ current->acl = obj->nested; >+ else >+ current->acl = newacl; >+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT) >+ security_audit(GR_INHERIT_ACL_MSG, current->acl->filename, >+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); >+ >+ current->is_writable = 0; >+ >+ /* ignore additional mmap checks for processes that are writable >+ by the default ACL */ >+ obj = chk_obj_label(dentry, mnt, default_role->root_label); >+ if (unlikely(obj->mode & GR_WRITE)) >+ current->is_writable = 1; >+ obj = chk_obj_label(dentry, mnt, current->role->root_label); >+ if (unlikely(obj->mode & GR_WRITE)) >+ current->is_writable = 1; >+ >+ gr_set_proc_res(); >+ >+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG >+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename); >+#endif >+ return; >+} >+ >+static __inline__ void >+do_handle_delete(const ino_t ino, const kdev_t dev) >+{ >+ struct acl_object_label *matchpo; >+ struct acl_subject_label *matchps; >+ struct acl_subject_label *i; >+ struct acl_role_label *role; >+ >+ for (role = role_list_head; role; role = role->next) { >+ for (i = role->proc_subject; i; i = i->next) { >+ if (unlikely(i->parent_subject && >+ (i->inode == ino) && >+ (i->device == dev))) >+ i->mode |= GR_DELETED; >+ if (unlikely((matchpo = >+ lookup_acl_obj_label(ino, dev, i)) != NULL)) >+ matchpo->mode |= GR_DELETED; >+ } >+ >+ if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)) >+ matchps->mode |= GR_DELETED; >+ } >+ >+ return; >+} >+ >+void >+gr_handle_delete(const ino_t ino, const kdev_t dev) >+{ >+ 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); >+ write_unlock(&gr_inode_lock); >+ >+ return; >+} >+ >+static __inline__ void >+update_acl_obj_label(const ino_t oldinode, const kdev_t olddevice, >+ const ino_t newinode, const kdev_t newdevice, >+ struct acl_subject_label *subj) >+{ >+ unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size); >+ struct acl_object_label **match; >+ struct acl_object_label *tmp; >+ __u8 i = 0; >+ >+ match = &subj->obj_hash[index]; >+ >+ while (*match && ((*match)->inode != oldinode || >+ (*match)->device != olddevice || >+ !((*match)->mode & GR_DELETED))) { >+ index = (index + (1 << i)) % subj->obj_hash_size; >+ match = &subj->obj_hash[index]; >+ i = (i + 1) % 32; >+ } >+ >+ if (*match && ((*match) != deleted_object) >+ && ((*match)->inode == oldinode) >+ && ((*match)->device == olddevice) >+ && ((*match)->mode & GR_DELETED)) { >+ tmp = *match; >+ tmp->inode = newinode; >+ tmp->device = newdevice; >+ tmp->mode &= ~GR_DELETED; >+ >+ *match = deleted_object; >+ >+ insert_acl_obj_label(tmp, subj); >+ } >+ >+ return; >+} >+ >+static __inline__ void >+update_acl_subj_label(const ino_t oldinode, const kdev_t olddevice, >+ const ino_t newinode, const kdev_t newdevice, >+ struct acl_role_label *role) >+{ >+ struct acl_subject_label **s_hash = role->subj_hash; >+ unsigned long subj_size = role->subj_hash_size; >+ unsigned long index = fhash(oldinode, olddevice, subj_size); >+ struct acl_subject_label **match; >+ struct acl_subject_label *tmp; >+ __u8 i = 0; >+ >+ match = &s_hash[index]; >+ >+ while (*match && ((*match)->inode != oldinode || >+ (*match)->device != olddevice || >+ !((*match)->mode & GR_DELETED))) { >+ index = (index + (1 << i)) % subj_size; >+ i = (i + 1) % 32; >+ match = &s_hash[index]; >+ } >+ >+ if (*match && (*match != deleted_subject) >+ && ((*match)->inode == oldinode) >+ && ((*match)->device == olddevice) >+ && ((*match)->mode & GR_DELETED)) { >+ tmp = *match; >+ >+ tmp->inode = newinode; >+ tmp->device = newdevice; >+ tmp->mode &= ~GR_DELETED; >+ >+ *match = deleted_subject; >+ >+ insert_acl_subj_label(tmp, role); >+ } >+ >+ return; >+} >+ >+static __inline__ void >+update_inodev_entry(const ino_t oldinode, const kdev_t olddevice, >+ const ino_t newinode, const kdev_t newdevice) >+{ >+ unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size); >+ struct name_entry **match; >+ struct name_entry *tmp; >+ __u8 i = 0; >+ >+ match = &inodev_set.n_hash[index]; >+ >+ while (*match >+ && ((*match)->inode != oldinode >+ || (*match)->device != olddevice)) { >+ index = (index + (1 << i)) % inodev_set.n_size; >+ i = (i + 1) % 32; >+ match = &inodev_set.n_hash[index]; >+ } >+ >+ if (*match && (*match != deleted_inodev) >+ && ((*match)->inode == oldinode) >+ && ((*match)->device == olddevice)) { >+ tmp = *match; >+ >+ tmp->inode = newinode; >+ tmp->device = newdevice; >+ >+ *match = deleted_inodev; >+ >+ insert_inodev_entry(tmp); >+ } >+ >+ return; >+} >+ >+static __inline__ void >+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry, >+ const struct vfsmount *mnt) >+{ >+ struct acl_subject_label *i; >+ struct acl_role_label *role; >+ >+ for (role = role_list_head; role; role = role->next) { >+ update_acl_subj_label(matchn->inode, matchn->device, >+ dentry->d_inode->i_ino, >+ dentry->d_inode->i_dev, role); >+ >+ for (i = role->proc_subject; i; i = i->next) { >+ if (unlikely(i->parent_subject && >+ (i->inode == dentry->d_inode->i_ino) && >+ (i->device == dentry->d_inode->i_dev))) { >+ i->inode = dentry->d_inode->i_ino; >+ i->device = dentry->d_inode->i_dev; >+ } >+ update_acl_obj_label(matchn->inode, matchn->device, >+ dentry->d_inode->i_ino, >+ dentry->d_inode->i_dev, i); >+ } >+ } >+ >+ update_inodev_entry(matchn->inode, matchn->device, >+ dentry->d_inode->i_ino, dentry->d_inode->i_dev); >+ >+ return; >+} >+ >+void >+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ struct name_entry *matchn; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return; >+ >+ matchn = lookup_name_entry(gr_to_filename(dentry, mnt)); >+ >+ if (unlikely((unsigned long)matchn)) { >+ write_lock(&gr_inode_lock); >+ do_handle_create(matchn, dentry, mnt); >+ write_unlock(&gr_inode_lock); >+ } >+ >+ return; >+} >+ >+int >+gr_handle_rename(struct inode *old_dir, struct inode *new_dir, >+ struct dentry *old_dentry, >+ struct dentry *new_dentry, >+ struct vfsmount *mnt, const __u8 replace) >+{ >+ struct name_entry *matchn; >+ int error = 0; >+ >+ matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt)); >+ >+ lock_kernel(); >+ error = vfs_rename(old_dir, old_dentry, new_dir, new_dentry); >+ unlock_kernel(); >+ >+ if (unlikely(error)) >+ return error; >+ >+ /* we wouldn't have to check d_inode if it weren't for >+ NFS silly-renaming >+ */ >+ >+ 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_dev) && >+ (old_dentry->d_inode->i_nlink <= 1))) >+ do_handle_delete(new_dentry->d_inode->i_ino, >+ new_dentry->d_inode->i_dev); >+ } >+ >+ if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino, >+ old_dentry->d_inode->i_dev) && >+ (old_dentry->d_inode->i_nlink <= 1))) >+ do_handle_delete(old_dentry->d_inode->i_ino, >+ old_dentry->d_inode->i_dev); >+ >+ if (unlikely((unsigned long)matchn)) >+ do_handle_create(matchn, old_dentry, mnt); >+ write_unlock(&gr_inode_lock); >+ >+ return error; >+} >+ >+static int >+lookup_special_role_auth(const char *rolename, unsigned char **salt, >+ unsigned char **sum) >+{ >+ struct acl_role_label *r; >+ struct role_transition *trans; >+ __u16 i; >+ int found = 0; >+ >+ /* check transition table */ >+ >+ for (trans = current->role->transitions; trans; trans = trans->next) { >+ if (!strcmp(rolename, trans->rolename)) { >+ found = 1; >+ break; >+ } >+ } >+ >+ if (!found) >+ return 0; >+ >+ /* handle special roles that do not require authentication */ >+ >+ for (r = role_list_head; r; r = r->next) { >+ if (!strcmp(rolename, r->rolename) >+ && (r->roletype & GR_ROLE_NOPW)) { >+ *salt = NULL; >+ *sum = NULL; >+ return 1; >+ } >+ } >+ >+ for (i = 0; i < num_sprole_pws; i++) { >+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) { >+ *salt = acl_special_roles[i]->salt; >+ *sum = acl_special_roles[i]->sum; >+ return 1; >+ } >+ } >+ >+ return 0; >+} >+ >+static void >+assign_special_role(char *rolename) >+{ >+ struct acl_object_label *obj; >+ struct acl_role_label *r; >+ struct acl_role_label *assigned = NULL; >+ struct task_struct *tsk; >+ struct file *filp; >+ >+ for (r = role_list_head; r; r = r->next) >+ if (!strcmp(rolename, r->rolename) && >+ (r->roletype & GR_ROLE_SPECIAL)) >+ assigned = r; >+ >+ if (!assigned) >+ return; >+ >+ tsk = current->p_pptr; >+ filp = tsk->exec_file; >+ >+ if (tsk && filp) { >+ tsk->is_writable = 0; >+ >+ acl_sp_role_value = (acl_sp_role_value % 65535) + 1; >+ tsk->acl_sp_role = 1; >+ tsk->acl_role_id = acl_sp_role_value; >+ tsk->role = assigned; >+ tsk->acl = >+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role); >+ >+ /* ignore additional mmap checks for processes that are writable >+ by the default ACL */ >+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); >+ if (unlikely(obj->mode & GR_WRITE)) >+ tsk->is_writable = 1; >+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label); >+ if (unlikely(obj->mode & GR_WRITE)) >+ tsk->is_writable = 1; >+ >+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG >+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid); >+#endif >+ } >+ >+ return; >+} >+ >+ssize_t >+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos) >+{ >+ struct gr_arg *arg; >+ unsigned char *sprole_salt; >+ unsigned char *sprole_sum; >+ int error = sizeof (struct gr_arg); >+ int error2 = 0; >+ >+ down(&gr_dev_sem); >+ >+ arg = (struct gr_arg *) buf; >+ >+ if (count != sizeof (struct gr_arg)) { >+ security_alert_good(GR_DEV_ACL_MSG, count, >+ (int) sizeof (struct gr_arg)); >+ error = -EINVAL; >+ goto out; >+ } >+ >+ if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) >+ && time_before_eq(gr_auth_expires, jiffies)) { >+ gr_auth_expires = 0; >+ gr_auth_attempts = 0; >+ } >+ >+ if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) { >+ error = -EFAULT; >+ goto out; >+ } >+ >+ if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, jiffies)) { >+ error = -EBUSY; >+ goto out; >+ } >+ >+ /* if non-root trying to do anything other than use a special role, >+ do not attempt authentication, do not count towards authentication >+ locking >+ */ >+ >+ if (gr_usermode->mode != SPROLE && current->uid) { >+ error = -EPERM; >+ goto out; >+ } >+ >+ /* ensure pw and special role name are null terminated */ >+ >+ gr_usermode->pw[GR_PW_LEN - 1] = '\0'; >+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0'; >+ >+ /* Okay. >+ * We have our enough of the argument structure..(we have yet >+ * to copy_from_user the tables themselves) . Copy the tables >+ * only if we need them, i.e. for loading operations. */ >+ >+ switch (gr_usermode->mode) { >+ case STATUS: >+ if (gr_status & GR_READY) >+ error = 1; >+ else >+ error = 2; >+ goto out; >+ case SHUTDOWN: >+ if ((gr_status & GR_READY) >+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { >+ gr_status &= ~GR_READY; >+ security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS); >+ free_variables(); >+ memset(gr_usermode, 0, sizeof (struct gr_arg)); >+ memset(gr_system_salt, 0, GR_SALT_LEN); >+ memset(gr_system_sum, 0, GR_SHA_LEN); >+ } else if (gr_status & GR_READY) { >+ security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS); >+ error = -EPERM; >+ } else { >+ security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS); >+ error = -EAGAIN; >+ } >+ break; >+ case ENABLE: >+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode))) >+ security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION); >+ else { >+ if (gr_status & GR_READY) >+ error = -EAGAIN; >+ else >+ error = error2; >+ security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION, >+ DEFAULTSECARGS); >+ } >+ break; >+ case RELOAD: >+ if (!(gr_status & GR_READY)) { >+ security_alert_good(GR_RELOADI_ACL_MSG); >+ error = -EAGAIN; >+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { >+ lock_kernel(); >+ gr_status &= ~GR_READY; >+ free_variables(); >+ if (!(error2 = gracl_init(gr_usermode))) { >+ unlock_kernel(); >+ security_alert_good(GR_RELOAD_ACL_MSG, >+ GR_VERSION); >+ } else { >+ unlock_kernel(); >+ error = error2; >+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION, >+ DEFAULTSECARGS); >+ } >+ } else { >+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION, >+ DEFAULTSECARGS); >+ error = -EPERM; >+ } >+ break; >+ case SEGVMOD: >+ if (unlikely(!(gr_status & GR_READY))) { >+ security_alert_good(GR_SEGVMODI_ACL_MSG, >+ DEFAULTSECARGS); >+ error = -EAGAIN; >+ break; >+ } >+ >+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) { >+ security_alert_good(GR_SEGVMODS_ACL_MSG, >+ DEFAULTSECARGS); >+ if (gr_usermode->segv_device && gr_usermode->segv_inode) { >+ struct acl_subject_label *segvacl; >+ segvacl = >+ lookup_acl_subj_label(gr_usermode->segv_inode, >+ gr_usermode->segv_device, >+ current->role); >+ if (segvacl) { >+ segvacl->crashes = 0; >+ segvacl->expires = 0; >+ } >+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) { >+ gr_remove_uid(gr_usermode->segv_uid); >+ } >+ } else { >+ security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS); >+ error = -EPERM; >+ } >+ break; >+ case SPROLE: >+ if (unlikely(!(gr_status & GR_READY))) { >+ security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS); >+ error = -EAGAIN; >+ break; >+ } >+ >+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) >+ && time_before_eq(current->role->expires, jiffies)) { >+ current->role->expires = 0; >+ current->role->auth_attempts = 0; >+ } >+ >+ if (time_after(current->role->expires, jiffies)) { >+ error = -EBUSY; >+ goto out; >+ } >+ >+ if (lookup_special_role_auth >+ (gr_usermode->sp_role, &sprole_salt, &sprole_sum) >+ && ((!sprole_salt && !sprole_sum) >+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) { >+ assign_special_role(gr_usermode->sp_role); >+ security_alert_good(GR_SPROLES_ACL_MSG, >+ (current->p_pptr) ? current-> >+ p_pptr->role->rolename : "", >+ acl_sp_role_value, DEFAULTSECARGS); >+ } else { >+ security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role, >+ DEFAULTSECARGS); >+ error = -EPERM; >+ current->role->auth_attempts++; >+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) { >+ current->role->expires = >+ jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ; >+ security_alert(GR_MAXROLEPW_ACL_MSG, >+ CONFIG_GRKERNSEC_ACL_MAXTRIES, >+ gr_usermode->sp_role, DEFAULTSECARGS); >+ } >+ >+ goto out; >+ } >+ break; >+ case UNSPROLE: >+ if (unlikely(!(gr_status & GR_READY))) { >+ security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS); >+ error = -EAGAIN; >+ break; >+ } >+ >+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) >+ && time_before_eq(current->role->expires, jiffies)) { >+ current->role->expires = 0; >+ current->role->auth_attempts = 0; >+ } >+ >+ if (time_after(current->role->expires, jiffies)) { >+ error = -EBUSY; >+ goto out; >+ } >+ >+ if ((current->role->roletype & GR_ROLE_SPECIAL) && >+ lookup_special_role_auth >+ (current->role->rolename, &sprole_salt, &sprole_sum) >+ && ((!sprole_salt && !sprole_sum) >+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) { >+ security_alert_good(GR_UNSPROLES_ACL_MSG, >+ (current->p_pptr) ? current-> >+ p_pptr->role->rolename : "", >+ (current->p_pptr) ? current-> >+ p_pptr->acl_role_id : 0, DEFAULTSECARGS); >+ gr_set_acls(1); >+ if (current->p_pptr) >+ current->p_pptr->acl_sp_role = 0; >+ } else { >+ security_alert(GR_UNSPROLEF_ACL_MSG, gr_usermode->sp_role, >+ DEFAULTSECARGS); >+ error = -EPERM; >+ current->role->auth_attempts++; >+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) { >+ current->role->expires = >+ jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ; >+ security_alert(GR_MAXROLEPW_ACL_MSG, >+ CONFIG_GRKERNSEC_ACL_MAXTRIES, >+ current->role->rolename, DEFAULTSECARGS); >+ } >+ >+ goto out; >+ } >+ break; >+ default: >+ security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode, >+ DEFAULTSECARGS); >+ error = -EINVAL; >+ break; >+ } >+ >+ if (error != -EPERM) >+ goto out; >+ >+ gr_auth_attempts++; >+ >+ if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) { >+ security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES); >+ gr_auth_expires = jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ; >+ } >+ >+ out: >+ up(&gr_dev_sem); >+ return error; >+} >+ >+int >+gr_set_acls(const int type) >+{ >+ struct acl_object_label *obj; >+ struct task_struct *task; >+ struct file *filp; >+ unsigned short i; >+ >+ read_lock(&tasklist_lock); >+ for_each_task(task) { >+ /* check to see if we're called from the exit handler, >+ if so, only replace ACLs that have inherited the admin >+ ACL */ >+ >+ if (type && (task->role != current->role || >+ task->acl_role_id != current->acl_role_id)) >+ continue; >+ >+ task->acl_role_id = 0; >+ >+ if ((filp = task->exec_file)) { >+ do_set_role_label(task, task->uid, task->gid); >+ >+ task->acl = >+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, >+ task->role); >+ if (task->acl) { >+ struct acl_subject_label *curr; >+ curr = task->acl; >+ >+ task->is_writable = 0; >+ /* ignore additional mmap checks for processes that are writable >+ by the default ACL */ >+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); >+ if (unlikely(obj->mode & GR_WRITE)) >+ task->is_writable = 1; >+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label); >+ if (unlikely(obj->mode & GR_WRITE)) >+ task->is_writable = 1; >+ >+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG >+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename); >+#endif >+ if (!(curr->mode & GR_LEARN)) >+ for (i = 0; i < RLIM_NLIMITS; i++) { >+ if (!(curr->resmask & (1 << i))) >+ continue; >+ >+ task->rlim[i].rlim_cur = >+ curr->res[i].rlim_cur; >+ task->rlim[i].rlim_max = >+ curr->res[i].rlim_max; >+ } >+ } else { >+ read_unlock(&tasklist_lock); >+ security_alert_good(GR_DEFACL_MSG, task->comm, >+ task->pid); >+ return 1; >+ } >+ } else { >+ // it's a kernel process >+ task->role = kernel_role; >+ task->acl = kernel_role->root_label; >+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN >+ task->acl->mode &= ~GR_FIND; >+#endif >+ } >+ } >+ read_unlock(&tasklist_lock); >+ return 0; >+} >+ >+void >+gr_learn_resource(const struct task_struct *task, >+ const int res, const unsigned long wanted) >+{ >+ struct acl_subject_label *acl; >+ >+ if (unlikely((gr_status & GR_READY) && >+ task->acl && (task->acl->mode & GR_LEARN))) >+ goto skip_reslog; >+ >+#ifdef CONFIG_GRKERNSEC_RESLOG >+ gr_log_resource(task, res, wanted); >+#endif >+ skip_reslog: >+ >+ if (unlikely(!(gr_status & GR_READY) || !wanted)) >+ return; >+ >+ acl = task->acl; >+ >+ if (likely(!acl || !(acl->mode & GR_LEARN) || >+ !(acl->resmask & (1 << (unsigned short) res)))) >+ return; >+ >+ if (wanted >= acl->res[res].rlim_cur) { >+ unsigned long res_add; >+ >+ res_add = wanted; >+ switch (res) { >+ case RLIMIT_CPU: >+ res_add += GR_RLIM_CPU_BUMP; >+ break; >+ case RLIMIT_FSIZE: >+ res_add += GR_RLIM_FSIZE_BUMP; >+ break; >+ case RLIMIT_DATA: >+ res_add += GR_RLIM_DATA_BUMP; >+ break; >+ case RLIMIT_STACK: >+ res_add += GR_RLIM_STACK_BUMP; >+ break; >+ case RLIMIT_CORE: >+ res_add += GR_RLIM_CORE_BUMP; >+ break; >+ case RLIMIT_RSS: >+ res_add += GR_RLIM_RSS_BUMP; >+ break; >+ case RLIMIT_NPROC: >+ res_add += GR_RLIM_NPROC_BUMP; >+ break; >+ case RLIMIT_NOFILE: >+ res_add += GR_RLIM_NOFILE_BUMP; >+ break; >+ case RLIMIT_MEMLOCK: >+ res_add += GR_RLIM_MEMLOCK_BUMP; >+ break; >+ case RLIMIT_AS: >+ res_add += GR_RLIM_AS_BUMP; >+ break; >+ case RLIMIT_LOCKS: >+ res_add += GR_RLIM_LOCKS_BUMP; >+ break; >+ } >+ >+ acl->res[res].rlim_cur = res_add; >+ >+ if (wanted > acl->res[res].rlim_max) >+ acl->res[res].rlim_max = res_add; >+ >+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename, >+ current->role->roletype, acl->filename, >+ acl->res[res].rlim_cur, acl->res[res].rlim_max, >+ "", (unsigned long) res); >+ } >+ >+ return; >+} >+ >+#ifdef CONFIG_SYSCTL >+extern struct proc_dir_entry *proc_sys_root; >+ >+__u32 >+gr_handle_sysctl(const struct ctl_table *table, const void *oldval, >+ const void *newval) >+{ >+ struct proc_dir_entry *tmp; >+ struct nameidata nd; >+ const char *proc_sys = "/proc/sys"; >+ char *path = gr_shared_page[0][smp_processor_id()]; >+ struct acl_object_label *obj; >+ unsigned short len = 0, pos = 0, depth = 0, i; >+ __u32 err = 0; >+ __u32 mode = 0; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return 1; >+ >+ if (oldval) >+ mode |= GR_READ; >+ if (newval) >+ mode |= GR_WRITE; >+ >+ /* convert the requested sysctl entry into a pathname */ >+ >+ for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) { >+ len += strlen(tmp->name); >+ len++; >+ depth++; >+ } >+ >+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) >+ return 0; // deny >+ >+ memset(path, 0, PAGE_SIZE); >+ >+ memcpy(path, proc_sys, strlen(proc_sys)); >+ >+ pos += strlen(proc_sys); >+ >+ for (; depth > 0; depth--) { >+ path[pos] = '/'; >+ pos++; >+ for (i = 1, tmp = table->de; tmp != proc_sys_root; >+ tmp = tmp->parent) { >+ if (depth == i) { >+ memcpy(path + pos, tmp->name, >+ strlen(tmp->name)); >+ pos += strlen(tmp->name); >+ } >+ i++; >+ } >+ } >+ >+ if (path_init(path, LOOKUP_FOLLOW, &nd)) >+ err = path_walk(path, &nd); >+ >+ if (err) >+ goto out; >+ >+ obj = chk_obj_label(nd.dentry, nd.mnt, current->acl); >+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS); >+ >+ if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) { >+ __u32 new_mode = mode; >+ >+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS); >+ >+ err = new_mode; >+ gr_log_learn(current->role, current->uid, current->gid, >+ current, path, new_mode); >+ } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) { >+ security_alert(GR_SYSCTL_ACL_MSG, "denied", path, >+ (mode & GR_READ) ? " reading" : "", >+ (mode & GR_WRITE) ? " writing" : "", >+ DEFAULTSECARGS); >+ err = 0; >+ } else if ((err & mode) != mode) { >+ err = 0; >+ } else if (((err & mode) == mode) && (err & GR_AUDITS)) { >+ security_audit(GR_SYSCTL_ACL_MSG, "successful", >+ path, (mode & GR_READ) ? " reading" : "", >+ (mode & GR_WRITE) ? " writing" : "", >+ DEFAULTSECARGS); >+ } >+ >+ path_release(&nd); >+ >+ out: >+ return err; >+} >+#endif >+ >+int >+gr_handle_ptrace(struct task_struct *task, const long request) >+{ >+ struct file *filp; >+ __u32 retmode; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return 0; >+ >+ filp = task->exec_file; >+ >+ if (unlikely(!filp)) >+ return 0; >+ >+ retmode = gr_search_file(filp->f_dentry, GR_PTRACERD, filp->f_vfsmnt); >+ >+ if (retmode & GR_PTRACERD) { >+ switch (request) { >+ case PTRACE_POKETEXT: >+ case PTRACE_POKEDATA: >+ case PTRACE_POKEUSR: >+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) >+ case PTRACE_SETREGS: >+ case PTRACE_SETFPREGS: >+#endif >+#ifdef CONFIG_X86 >+ case PTRACE_SETFPXREGS: >+#endif >+#ifdef CONFIG_ALTIVEC >+ case PTRACE_SETVRREGS: >+#endif >+ return 1; >+ default: >+ return 0; >+ } >+ } else if (!(current->acl->mode & GR_OVERRIDE) && >+ !(current->role->roletype & GR_ROLE_GOD) >+ && (current->acl != task->acl >+ || (current->acl != current->role->root_label >+ && current->pid != task->pid))) { >+ security_alert(GR_PTRACE_ACL_MSG, >+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt), >+ task->comm, task->pid, DEFAULTSECARGS); >+ return 1; >+ } >+ >+ return 0; >+} >+ >+int >+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ __u32 retmode; >+ struct acl_subject_label *subj; >+ >+ if (unlikely(!(gr_status & GR_READY))) >+ return 0; >+ >+ if (unlikely >+ ((current->ptrace & PT_PTRACED) >+ && !(current->acl->mode & GR_OVERRIDE))) >+ retmode = gr_search_file(dentry, GR_PTRACERD, mnt); >+ else >+ return 0; >+ >+ subj = chk_subj_label(dentry, mnt, current->role); >+ >+ if (!(retmode & GR_PTRACERD) && >+ !(current->role->roletype & GR_ROLE_GOD) && >+ (current->acl != subj)) { >+ security_alert(GR_PTRACE_EXEC_ACL_MSG, >+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); >+ return 1; >+ } >+ >+ return 0; >+} >+ >+int >+gr_handle_mmap(const struct file *filp, const unsigned long prot) >+{ >+ struct acl_object_label *obj, *obj2; >+ >+ if (unlikely(!(gr_status & GR_READY) || >+ (current->acl->mode & GR_OVERRIDE) || !filp || >+ !(prot & PROT_EXEC))) >+ return 0; >+ >+ if (unlikely(current->is_writable)) >+ return 0; >+ >+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label); >+ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, >+ current->role->root_label); >+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) { >+ security_alert(GR_WRITLIB_ACL_MSG, >+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt), >+ DEFAULTSECARGS); >+ return 1; >+ } >+ >+ return 0; >+} >+ >+int >+gr_acl_handle_mmap(const struct file *file, const unsigned long prot) >+{ >+ __u32 mode; >+ >+ if (unlikely(!file || !(prot & PROT_EXEC))) >+ return 1; >+ >+ mode = >+ gr_search_file(file->f_dentry, >+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, >+ file->f_vfsmnt); >+ >+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) { >+ security_alert(GR_MMAP_ACL_MSG, "denied", >+ gr_to_filename(file->f_dentry, file->f_vfsmnt), >+ DEFAULTSECARGS); >+ return 0; >+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) { >+ return 0; >+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) { >+ security_audit(GR_MMAP_ACL_MSG, "successful", >+ gr_to_filename(file->f_dentry, file->f_vfsmnt), >+ DEFAULTSECARGS); >+ return 1; >+ } >+ >+ return 1; >+} >+ >+int >+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot) >+{ >+ __u32 mode; >+ >+ if (unlikely(!file || !(prot & PROT_EXEC))) >+ return 1; >+ >+ mode = >+ gr_search_file(file->f_dentry, >+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS, >+ file->f_vfsmnt); >+ >+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) { >+ security_alert(GR_MPROTECT_ACL_MSG, "denied", >+ gr_to_filename(file->f_dentry, file->f_vfsmnt), >+ DEFAULTSECARGS); >+ return 0; >+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) { >+ return 0; >+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) { >+ security_audit(GR_MPROTECT_ACL_MSG, "successful", >+ gr_to_filename(file->f_dentry, file->f_vfsmnt), >+ DEFAULTSECARGS); >+ return 1; >+ } >+ >+ return 1; >+} >+ >+void >+gr_acl_handle_psacct(struct task_struct *task, const long code) >+{ >+ unsigned long runtime; >+ unsigned long cputime; >+ unsigned int wday, cday; >+ __u8 whr, chr; >+ __u8 wmin, cmin; >+ __u8 wsec, csec; >+ char cur_tty[64] = { 0 }; >+ char parent_tty[64] = { 0 }; >+ >+ if (unlikely(!(gr_status & GR_READY) || !task->acl || >+ !(task->acl->mode & GR_PROCACCT))) >+ return; >+ >+ runtime = (jiffies - task->start_time) / HZ; >+ wday = runtime / (3600 * 24); >+ runtime -= wday * (3600 * 24); >+ whr = runtime / 3600; >+ runtime -= whr * 3600; >+ wmin = runtime / 60; >+ runtime -= wmin * 60; >+ wsec = runtime; >+ >+ cputime = (task->times.tms_utime + task->times.tms_stime) / HZ; >+ cday = cputime / (3600 * 24); >+ cputime -= cday * (3600 * 24); >+ chr = cputime / 3600; >+ cputime -= chr * 3600; >+ cmin = cputime / 60; >+ cputime -= cmin * 60; >+ csec = cputime; >+ >+ security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm, >+ task->pid, NIPQUAD(task->curr_ip), tty_name(task->tty, >+ cur_tty), >+ task->uid, task->euid, task->gid, task->egid, wday, whr, >+ wmin, wsec, cday, chr, cmin, csec, >+ (task-> >+ flags & PF_SIGNALED) ? "killed by signal" : "exited", >+ code, gr_parent_task_fullpath(task), >+ task->p_pptr->comm, task->p_pptr->pid, >+ NIPQUAD(task->p_pptr->curr_ip), >+ tty_name(task->p_pptr->tty, parent_tty), >+ task->p_pptr->uid, task->p_pptr->euid, task->p_pptr->gid, >+ task->p_pptr->egid); >+ >+ return; >+} >+ >+void gr_set_kernel_label(struct task_struct *task) >+{ >+ if (gr_status & GR_READY) { >+ task->role = kernel_role; >+ task->acl = kernel_role->root_label; >+ } >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl_alloc.c linux-2.4.22-ppc-dev/grsecurity/gracl_alloc.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl_alloc.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl_alloc.c 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,94 @@ >+/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */ >+ >+#include <linux/kernel.h> >+#include <linux/mm.h> >+#include <linux/slab.h> >+#include <linux/vmalloc.h> >+#include <linux/gracl.h> >+#include <linux/grsecurity.h> >+ >+static unsigned long alloc_stack_next = 1; >+static unsigned long alloc_stack_size = 1; >+static void **alloc_stack; >+ >+static __inline__ int >+alloc_pop(void) >+{ >+ if ((alloc_stack_next - 1) == 0) >+ return 0; >+ >+ if (*(alloc_stack + alloc_stack_next - 2)) >+ kfree(*(alloc_stack + alloc_stack_next - 2)); >+ >+ alloc_stack_next--; >+ >+ return 1; >+} >+ >+static __inline__ void >+alloc_push(void *buf) >+{ >+ if (alloc_stack_next >= alloc_stack_size) >+ BUG(); >+ >+ *(alloc_stack + alloc_stack_next - 1) = buf; >+ >+ alloc_stack_next++; >+ >+ return; >+} >+ >+void * >+acl_alloc(unsigned long len) >+{ >+ void *ret; >+ >+ if (len > PAGE_SIZE) >+ BUG(); >+ >+ ret = kmalloc(len, GFP_KERNEL); >+ >+ if (ret) >+ alloc_push(ret); >+ >+ return ret; >+} >+ >+void >+acl_free_all(void) >+{ >+ if (gr_acl_is_enabled() || !alloc_stack) >+ return; >+ >+ while (alloc_pop()) ; >+ >+ if (alloc_stack) { >+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE) >+ kfree(alloc_stack); >+ else >+ vfree(alloc_stack); >+ } >+ >+ alloc_stack = NULL; >+ alloc_stack_size = 1; >+ alloc_stack_next = 1; >+ >+ return; >+} >+ >+int >+acl_alloc_stack_init(unsigned long size) >+{ >+ if ((size * sizeof (void *)) <= PAGE_SIZE) >+ alloc_stack = >+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL); >+ else >+ alloc_stack = (void **) vmalloc(size * sizeof (void *)); >+ >+ alloc_stack_size = size; >+ >+ if (!alloc_stack) >+ return 0; >+ else >+ return 1; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl_cap.c linux-2.4.22-ppc-dev/grsecurity/gracl_cap.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl_cap.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl_cap.c 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,71 @@ >+/* capability handling routines, (c) Brad Spengler 2002,2003 */ >+ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/capability.h> >+#include <linux/gracl.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+static const char *captab_log[29] = { >+ "CAP_CHOWN", >+ "CAP_DAC_OVERRIDE", >+ "CAP_DAC_READ_SEARCH", >+ "CAP_FOWNER", >+ "CAP_FSETID", >+ "CAP_KILL", >+ "CAP_SETGID", >+ "CAP_SETUID", >+ "CAP_SETPCAP", >+ "CAP_LINUX_IMMUTABLE", >+ "CAP_NET_BIND_SERVICE", >+ "CAP_NET_BROADCAST", >+ "CAP_NET_ADMIN", >+ "CAP_NET_RAW", >+ "CAP_IPC_LOCK", >+ "CAP_IPC_OWNER", >+ "CAP_SYS_MODULE", >+ "CAP_SYS_RAWIO", >+ "CAP_SYS_CHROOT", >+ "CAP_SYS_PTRACE", >+ "CAP_SYS_PACCT", >+ "CAP_SYS_ADMIN", >+ "CAP_SYS_BOOT", >+ "CAP_SYS_NICE", >+ "CAP_SYS_RESOURCE", >+ "CAP_SYS_TIME", >+ "CAP_SYS_TTY_CONFIG", >+ "CAP_MKNOD", >+ "CAP_LEASE" >+}; >+ >+int >+gr_is_capable(const int cap) >+{ >+ struct acl_subject_label *curracl; >+ >+ if (!gr_acl_is_enabled()) >+ return 1; >+ >+ curracl = current->acl; >+ >+ if (!cap_raised(curracl->cap_lower, cap)) >+ return 1; >+ >+ if ((curracl->mode & GR_LEARN) >+ && cap_raised(current->cap_effective, cap)) { >+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename, >+ current->role->roletype, current->uid, >+ current->gid, current->exec_file ? >+ gr_to_filename(current->exec_file->f_dentry, >+ current->exec_file->f_vfsmnt) : curracl->filename, >+ curracl->filename, 0UL, >+ 0UL, "", (unsigned long) cap, NIPQUAD(current->curr_ip)); >+ return 1; >+ } >+ >+ if ((cap >= 0) && (cap < 29) && cap_raised(current->cap_effective, cap)) >+ security_alert(GR_CAP_ACL_MSG, captab_log[cap], DEFAULTSECARGS); >+ >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl_fs.c linux-2.4.22-ppc-dev/grsecurity/gracl_fs.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl_fs.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl_fs.c 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,469 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/types.h> >+#include <linux/fs.h> >+#include <linux/file.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+#include <linux/gracl.h> >+ >+__u32 >+gr_acl_handle_hidden_file(const struct dentry * dentry, >+ const struct vfsmount * mnt) >+{ >+ __u32 mode; >+ >+ if (unlikely(!dentry->d_inode)) >+ return GR_FIND; >+ >+ mode = >+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt); >+ >+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) { >+ security_audit(GR_HIDDEN_ACL_MSG, "successful", >+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); >+ return mode; >+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) { >+ security_alert(GR_HIDDEN_ACL_MSG, "denied", >+ gr_to_filename(dentry, mnt), >+ DEFAULTSECARGS); >+ return 0; >+ } else if (unlikely(!(mode & GR_FIND))) >+ return 0; >+ >+ return GR_FIND; >+} >+ >+__u32 >+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, >+ const int fmode) >+{ >+ __u32 reqmode = GR_FIND; >+ __u32 mode; >+ >+ if (unlikely(!dentry->d_inode)) >+ return reqmode; >+ >+ if (unlikely(fmode & O_APPEND)) >+ reqmode |= GR_APPEND; >+ else if (unlikely(fmode & FMODE_WRITE)) >+ reqmode |= GR_WRITE; >+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) >+ reqmode |= GR_READ; >+ >+ mode = >+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, >+ mnt); >+ >+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { >+ security_audit(GR_OPEN_ACL_MSG, "successful", >+ gr_to_filename(dentry, mnt), >+ reqmode & GR_READ ? " reading" : "", >+ reqmode & GR_WRITE ? " writing" : >+ reqmode & GR_APPEND ? " appending" : "", >+ DEFAULTSECARGS); >+ return reqmode; >+ } else >+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) >+ { >+ security_alert(GR_OPEN_ACL_MSG, "denied", >+ gr_to_filename(dentry, mnt), >+ reqmode & GR_READ ? " reading" : "", >+ reqmode & GR_WRITE ? " writing" : reqmode & >+ GR_APPEND ? " appending" : "", DEFAULTSECARGS); >+ return 0; >+ } else if (unlikely((mode & reqmode) != reqmode)) >+ return 0; >+ >+ return reqmode; >+} >+ >+__u32 >+gr_acl_handle_creat(const struct dentry * dentry, >+ const struct dentry * p_dentry, >+ const struct vfsmount * p_mnt, const int fmode, >+ const int imode) >+{ >+ __u32 reqmode = GR_WRITE | GR_CREATE; >+ __u32 mode; >+ >+ if (unlikely(fmode & O_APPEND)) >+ reqmode |= GR_APPEND; >+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY))) >+ reqmode |= GR_READ; >+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID)))) >+ reqmode |= GR_SETID; >+ >+ mode = >+ gr_check_create(dentry, p_dentry, p_mnt, >+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); >+ >+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { >+ security_audit(GR_CREATE_ACL_MSG, "successful", >+ gr_to_filename(dentry, p_mnt), >+ reqmode & GR_READ ? " reading" : "", >+ reqmode & GR_WRITE ? " writing" : >+ reqmode & GR_APPEND ? " appending" : "", >+ DEFAULTSECARGS); >+ return reqmode; >+ } else >+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) >+ { >+ security_alert(GR_CREATE_ACL_MSG, "denied", >+ gr_to_filename(dentry, p_mnt), >+ reqmode & GR_READ ? " reading" : "", >+ reqmode & GR_WRITE ? " writing" : reqmode & >+ GR_APPEND ? " appending" : "", DEFAULTSECARGS); >+ return 0; >+ } else if (unlikely((mode & reqmode) != reqmode)) >+ return 0; >+ >+ return reqmode; >+} >+ >+__u32 >+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt, >+ const int fmode) >+{ >+ __u32 mode, reqmode = GR_FIND; >+ >+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode)) >+ reqmode |= GR_EXEC; >+ if (fmode & S_IWOTH) >+ reqmode |= GR_WRITE; >+ if (fmode & S_IROTH) >+ reqmode |= GR_READ; >+ >+ mode = >+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, >+ mnt); >+ >+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) { >+ security_audit(GR_ACCESS_ACL_MSG, "successful", >+ gr_to_filename(dentry, mnt), >+ reqmode & GR_READ ? " reading" : "", >+ reqmode & GR_WRITE ? " writing" : "", >+ reqmode & GR_EXEC ? " executing" : "", >+ DEFAULTSECARGS); >+ return reqmode; >+ } else >+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS))) >+ { >+ security_alert(GR_ACCESS_ACL_MSG, "denied", >+ gr_to_filename(dentry, mnt), >+ reqmode & GR_READ ? " reading" : "", >+ reqmode & GR_WRITE ? " writing" : "", >+ reqmode & GR_EXEC ? " executing" : "", >+ DEFAULTSECARGS); >+ return 0; >+ } else if (unlikely((mode & reqmode) != reqmode)) >+ return 0; >+ >+ return reqmode; >+} >+ >+#define generic_fs_handler(dentry, mnt, reqmode, fmt) \ >+{ \ >+ __u32 mode; \ >+ \ >+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \ >+ \ >+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \ >+ security_audit(fmt, "successful", \ >+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); \ >+ return mode; \ >+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \ >+ security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \ >+ DEFAULTSECARGS); \ >+ return 0; \ >+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \ >+ return 0; \ >+ \ >+ return (reqmode); \ >+} >+ >+__u32 >+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) >+{ >+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG); >+} >+ >+__u32 >+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG); >+} >+ >+__u32 >+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG); >+} >+ >+__u32 >+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG); >+} >+ >+__u32 >+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt, >+ mode_t mode) >+{ >+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { >+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, >+ GR_FCHMOD_ACL_MSG); >+ } else { >+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG); >+ } >+} >+ >+__u32 >+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt, >+ mode_t mode) >+{ >+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) { >+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID, >+ GR_CHMOD_ACL_MSG); >+ } else { >+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG); >+ } >+} >+ >+__u32 >+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG); >+} >+ >+__u32 >+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG); >+} >+ >+__u32 >+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE, >+ GR_UNIXCONNECT_ACL_MSG); >+} >+ >+__u32 >+gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt, >+ const ino_t ino) >+{ >+ if (likely((unsigned long)(dentry->d_inode))) { >+ struct dentry d = *dentry; >+ struct inode inode = *(dentry->d_inode); >+ >+ inode.i_ino = ino; >+ d.d_inode = &inode; >+ >+ if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt))) >+ return 0; >+ } >+ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_link(const struct dentry * new_dentry, >+ const struct dentry * parent_dentry, >+ const struct vfsmount * parent_mnt, >+ const struct dentry * old_dentry, >+ const struct vfsmount * old_mnt, const char *to) >+{ >+ __u32 needmode = GR_WRITE | GR_CREATE; >+ __u32 mode; >+ >+ mode = >+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry, >+ old_mnt); >+ >+ if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) { >+ security_audit(GR_LINK_ACL_MSG, "successful", >+ gr_to_filename(old_dentry, old_mnt), to, >+ DEFAULTSECARGS); >+ return mode; >+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { >+ security_alert(GR_LINK_ACL_MSG, "denied", >+ gr_to_filename(old_dentry, old_mnt), to, >+ DEFAULTSECARGS); >+ return 0; >+ } else if (unlikely((mode & needmode) != needmode)) >+ return 0; >+ >+ return (GR_WRITE | GR_CREATE); >+} >+ >+__u32 >+gr_acl_handle_symlink(const struct dentry * new_dentry, >+ const struct dentry * parent_dentry, >+ const struct vfsmount * parent_mnt, const char *from) >+{ >+ __u32 needmode = GR_WRITE | GR_CREATE; >+ __u32 mode; >+ >+ mode = >+ gr_check_create(new_dentry, parent_dentry, parent_mnt, >+ GR_CREATE | GR_AUDIT_CREATE | >+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS); >+ >+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) { >+ security_audit(GR_SYMLINK_ACL_MSG, "successful", >+ from, gr_to_filename(new_dentry, parent_mnt), >+ DEFAULTSECARGS); >+ return mode; >+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) { >+ security_alert(GR_SYMLINK_ACL_MSG, "denied", >+ from, gr_to_filename(new_dentry, parent_mnt), >+ DEFAULTSECARGS); >+ return 0; >+ } else if (unlikely((mode & needmode) != needmode)) >+ return 0; >+ >+ return (GR_WRITE | GR_CREATE); >+} >+ >+#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \ >+{ \ >+ __u32 mode; \ >+ \ >+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \ >+ \ >+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \ >+ security_audit(fmt, "successful", \ >+ gr_to_filename(new_dentry, parent_mnt), \ >+ DEFAULTSECARGS); \ >+ return mode; \ >+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \ >+ security_alert(fmt, "denied", \ >+ gr_to_filename(new_dentry, parent_mnt), \ >+ DEFAULTSECARGS); \ >+ return 0; \ >+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \ >+ return 0; \ >+ \ >+ return (reqmode); \ >+} >+ >+__u32 >+gr_acl_handle_mknod(const struct dentry * new_dentry, >+ const struct dentry * parent_dentry, >+ const struct vfsmount * parent_mnt, >+ const int mode) >+{ >+ __u32 reqmode = GR_WRITE | GR_CREATE; >+ if (unlikely(mode & (S_ISUID | S_ISGID))) >+ reqmode |= GR_SETID; >+ >+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, >+ reqmode, GR_MKNOD_ACL_MSG); >+} >+ >+__u32 >+gr_acl_handle_mkdir(const struct dentry *new_dentry, >+ const struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt) >+{ >+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, >+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG); >+} >+ >+#define RENAME_CHECK_SUCCESS(old, new) \ >+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \ >+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ))) >+ >+int >+gr_acl_handle_rename(struct dentry *new_dentry, >+ struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt, >+ struct dentry *old_dentry, >+ struct inode *old_parent_inode, >+ struct vfsmount *old_mnt, const char *newname) >+{ >+ __u8 gr_replace = 1; >+ __u32 comp1, comp2; >+ int error = 0; >+ >+ if (unlikely(!gr_acl_is_enabled())) >+ return 1; >+ >+ if (!new_dentry->d_inode) { >+ gr_replace = 0; >+ >+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt, >+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ | >+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS); >+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE | >+ GR_DELETE | GR_AUDIT_DELETE | >+ GR_AUDIT_READ | GR_AUDIT_WRITE | >+ GR_SUPPRESS, old_mnt); >+ } else { >+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE | >+ GR_CREATE | GR_DELETE | >+ GR_AUDIT_CREATE | GR_AUDIT_DELETE | >+ GR_AUDIT_READ | GR_AUDIT_WRITE | >+ GR_SUPPRESS, parent_mnt); >+ comp2 = >+ gr_search_file(old_dentry, >+ GR_READ | GR_WRITE | GR_AUDIT_READ | >+ GR_DELETE | GR_AUDIT_DELETE | >+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt); >+ } >+ >+ if (RENAME_CHECK_SUCCESS(comp1, comp2) && >+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS))) >+ security_audit(GR_RENAME_ACL_MSG, "successful", >+ gr_to_filename(old_dentry, old_mnt), >+ newname, DEFAULTSECARGS); >+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS) >+ && !(comp2 & GR_SUPPRESS)) { >+ security_alert(GR_RENAME_ACL_MSG, "denied", >+ gr_to_filename(old_dentry, old_mnt), newname, >+ DEFAULTSECARGS); >+ error = -EACCES; >+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2))) >+ error = -EACCES; >+ >+ if (error) >+ return error; >+ >+ error = gr_handle_rename(old_parent_inode, parent_dentry->d_inode, >+ old_dentry, new_dentry, old_mnt, gr_replace); >+ >+ return error; >+} >+ >+void >+gr_acl_handle_exit(void) >+{ >+ u16 id; >+ char *rolename; >+ >+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) { >+ id = current->acl_role_id; >+ rolename = current->role->rolename; >+ gr_set_acls(1); >+ security_alert_good(GR_SPROLEL_ACL_MSG, >+ rolename, id, DEFAULTSECARGS); >+ } >+ >+ if (current->exec_file) { >+ fput(current->exec_file); >+ current->exec_file = NULL; >+ } >+} >+ >+int >+gr_acl_handle_procpidmem(const struct task_struct *task) >+{ >+ if (unlikely(!gr_acl_is_enabled())) >+ return 0; >+ >+ if (task->acl->mode & GR_PROTPROCFD) >+ return -EACCES; >+ >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl_ip.c linux-2.4.22-ppc-dev/grsecurity/gracl_ip.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl_ip.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl_ip.c 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,235 @@ >+/* >+ * grsecurity/gracl_ip.c >+ * Copyright Brad Spengler 2002, 2003 >+ * >+ */ >+ >+#include <linux/kernel.h> >+#include <asm/uaccess.h> >+#include <asm/errno.h> >+#include <net/sock.h> >+#include <linux/file.h> >+#include <linux/fs.h> >+#include <linux/net.h> >+#include <linux/in.h> >+#include <linux/skbuff.h> >+#include <linux/ip.h> >+#include <linux/udp.h> >+#include <linux/smp_lock.h> >+#include <linux/types.h> >+#include <linux/sched.h> >+#include <linux/gracl.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+#define GR_BIND 0x01 >+#define GR_CONNECT 0x02 >+ >+static const char * gr_protocols[256] = { >+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt", >+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet", >+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1", >+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp", >+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++", >+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre", >+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile", >+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63", >+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv", >+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", >+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", >+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp", >+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim", >+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip", >+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp", >+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup", >+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135", >+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143", >+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151", >+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159", >+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167", >+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175", >+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183", >+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191", >+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199", >+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207", >+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215", >+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223", >+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231", >+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239", >+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247", >+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255", >+ }; >+ >+static const char * gr_socktypes[11] = { >+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", >+ "unknown:7", "unknown:8", "unknown:9", "packet" >+ }; >+ >+static __inline__ const char * >+gr_proto_to_name(unsigned char proto) >+{ >+ return gr_protocols[proto]; >+} >+ >+static __inline__ const char * >+gr_socktype_to_name(unsigned char type) >+{ >+ return gr_socktypes[type]; >+} >+ >+int >+gr_search_socket(const int domain, const int type, const int protocol) >+{ >+ struct acl_subject_label *curr; >+ >+ if (unlikely(!gr_acl_is_enabled())) >+ goto exit; >+ >+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET) >+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255)) >+ goto exit; // let the kernel handle it >+ >+ curr = current->acl; >+ >+ if (!curr->ips) >+ goto exit; >+ >+ if ((curr->ip_type & (1 << type)) && >+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32)))) >+ goto exit; >+ >+ if (curr->mode & GR_LEARN) { >+ /* we don't place acls on raw sockets , and sometimes >+ dgram/ip sockets are opened for ioctl and not >+ bind/connect, so we'll fake a bind learn log */ >+ if (type == SOCK_RAW || type == SOCK_PACKET) { >+ __u32 fakeip = 0; >+ security_learn(GR_IP_LEARN_MSG, current->role->rolename, >+ current->role->roletype, current->uid, >+ current->gid, current->exec_file ? >+ gr_to_filename(current->exec_file->f_dentry, >+ current->exec_file->f_vfsmnt) : >+ curr->filename, curr->filename, >+ NIPQUAD(fakeip), 0, type, >+ protocol, GR_CONNECT, NIPQUAD(current->curr_ip)); >+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) { >+ __u32 fakeip = 0; >+ security_learn(GR_IP_LEARN_MSG, current->role->rolename, >+ current->role->roletype, current->uid, >+ current->gid, current->exec_file ? >+ gr_to_filename(current->exec_file->f_dentry, >+ current->exec_file->f_vfsmnt) : >+ curr->filename, curr->filename, >+ NIPQUAD(fakeip), 0, type, >+ protocol, GR_BIND, NIPQUAD(current->curr_ip)); >+ } >+ /* we'll log when they use connect or bind */ >+ goto exit; >+ } >+ >+ security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type), >+ gr_proto_to_name(protocol), DEFAULTSECARGS); >+ >+ return 0; >+ exit: >+ return 1; >+} >+ >+static __inline__ int >+gr_search_connectbind(const int mode, const struct sock *sk, >+ const struct sockaddr_in *addr, const int type) >+{ >+ struct acl_subject_label *curr; >+ struct acl_ip_label *ip; >+ unsigned long i; >+ __u32 ip_addr = 0; >+ __u16 ip_port = 0; >+ >+ if (unlikely(!gr_acl_is_enabled() || sk->family != PF_INET)) >+ return 1; >+ >+ curr = current->acl; >+ >+ if (!curr->ips) >+ return 1; >+ >+ ip_addr = addr->sin_addr.s_addr; >+ ip_port = ntohs(addr->sin_port); >+ >+ for (i = 0; i < curr->ip_num; i++) { >+ ip = *(curr->ips + i); >+ if ((ip->mode & mode) && >+ (ip_port >= ip->low) && >+ (ip_port <= ip->high) && >+ ((ntohl(ip_addr) & ip->netmask) == >+ (ntohl(ip->addr) & ip->netmask)) >+ && (ip-> >+ proto[sk->protocol / 32] & (1 << (sk->protocol % 32))) >+ && (ip->type & (1 << type))) >+ return 1; >+ } >+ >+ if (curr->mode & GR_LEARN) { >+ security_learn(GR_IP_LEARN_MSG, current->role->rolename, >+ current->role->roletype, current->uid, >+ current->gid, current->exec_file ? >+ gr_to_filename(current->exec_file->f_dentry, >+ current->exec_file->f_vfsmnt) : >+ curr->filename, curr->filename, >+ NIPQUAD(ip_addr), ip_port, type, >+ sk->protocol, mode, NIPQUAD(current->curr_ip)); >+ return 1; >+ } >+ >+ if (mode == GR_BIND) >+ security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port, >+ gr_socktype_to_name(type), gr_proto_to_name(sk->protocol), >+ DEFAULTSECARGS); >+ else if (mode == GR_CONNECT) >+ security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port, >+ gr_socktype_to_name(type), gr_proto_to_name(sk->protocol), >+ DEFAULTSECARGS); >+ >+ return 0; >+} >+ >+int >+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr) >+{ >+ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type); >+} >+ >+int >+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr) >+{ >+ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type); >+} >+ >+int >+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr) >+{ >+ if (addr) >+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM); >+ else { >+ struct sockaddr_in sin; >+ >+ sin.sin_addr.s_addr = sk->daddr; >+ sin.sin_port = sk->dport; >+ >+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM); >+ } >+} >+ >+int >+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb) >+{ >+ struct sockaddr_in sin; >+ >+ if (unlikely(skb->len < sizeof (struct udphdr))) >+ return 1; // skip this packet >+ >+ sin.sin_addr.s_addr = skb->nh.iph->saddr; >+ sin.sin_port = skb->h.uh->source; >+ >+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM); >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl_learn.c linux-2.4.22-ppc-dev/grsecurity/gracl_learn.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl_learn.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl_learn.c 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,228 @@ >+#include <linux/kernel.h> >+#include <linux/mm.h> >+#include <linux/sched.h> >+#include <linux/poll.h> >+#include <linux/smp_lock.h> >+#include <linux/string.h> >+#include <linux/file.h> >+#include <linux/types.h> >+#include <linux/vmalloc.h> >+#include <linux/grinternal.h> >+ >+extern ssize_t write_grsec_handler(struct file * file, const char * buf, >+ size_t count, loff_t *ppos); >+extern int gr_acl_is_enabled(void); >+ >+static DECLARE_WAIT_QUEUE_HEAD(learn_wait); >+static DECLARE_WAIT_QUEUE_HEAD(input_wait); >+static atomic_t learn_buffer_count = ATOMIC_INIT(0); >+static int gr_learn_attached; >+ >+#define LEARN_BUFFER_SLOTS 256 >+#define LEARN_BUFFER_SIZE 16384 >+ >+static spinlock_t learn_buffer_lock[LEARN_BUFFER_SLOTS] = { [0 ... (LEARN_BUFFER_SLOTS - 1)] = SPIN_LOCK_UNLOCKED }; >+static char *learn_buffer[LEARN_BUFFER_SLOTS]; >+static int learn_buffer_len[LEARN_BUFFER_SLOTS]; >+ >+static ssize_t >+read_learn(struct file *file, char * buf, size_t count, loff_t * ppos) >+{ >+ DECLARE_WAITQUEUE(wait, current); >+ ssize_t retval = 0; >+ char *tmp; >+ unsigned int len; >+ int i; >+ >+ add_wait_queue(&learn_wait, &wait); >+ set_current_state(TASK_INTERRUPTIBLE); >+ do { >+ if (atomic_read(&learn_buffer_count) > 1) >+ break; >+ >+ if (file->f_flags & O_NONBLOCK) { >+ retval = -EAGAIN; >+ goto out; >+ } >+ if (signal_pending(current)) { >+ retval = -ERESTARTSYS; >+ goto out; >+ } >+ >+ schedule(); >+ } while (1); >+ >+ >+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) { >+ spin_lock(&learn_buffer_lock[i]); >+ len = learn_buffer_len[i]; >+ tmp = learn_buffer[i]; >+ if (!len || !tmp) { >+ spin_unlock(&learn_buffer_lock[i]); >+ continue; >+ } >+ learn_buffer[i] = NULL; >+ learn_buffer_len[i] = 0; >+ spin_unlock(&learn_buffer_lock[i]); >+ >+ if (count < ((i * LEARN_BUFFER_SIZE) + len)) { >+ retval = -EINVAL; >+ vfree(tmp); >+ goto out; >+ } >+ if (copy_to_user(buf + (i * LEARN_BUFFER_SIZE), tmp, len)) { >+ retval = -EFAULT; >+ vfree(tmp); >+ goto out; >+ } >+ >+ retval += len; >+ vfree(tmp); >+ atomic_dec(&learn_buffer_count); >+ atomic_dec(&learn_buffer_count); >+ } >+ >+ wake_up(&input_wait); >+out: >+ set_current_state(TASK_RUNNING); >+ remove_wait_queue(&learn_wait, &wait); >+ return retval; >+} >+ >+static unsigned int >+poll_learn(struct file * file, poll_table * wait) >+{ >+ poll_wait(file, &learn_wait, wait); >+ >+ if (atomic_read(&learn_buffer_count) > 1) >+ return (POLLIN | POLLRDNORM); >+ >+ return 0; >+} >+ >+void >+gr_clear_learn_entries(void) >+{ >+ int i; >+ >+ atomic_set(&learn_buffer_count, 0); >+ wake_up(&input_wait); >+ >+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) { >+ if (learn_buffer_len[i]) { >+ vfree(learn_buffer[i]); >+ learn_buffer[i] = NULL; >+ learn_buffer_len[i] = 0; >+ } >+ } >+ >+ return; >+} >+ >+void >+gr_add_learn_entry(const char *fmt, ...) >+{ >+ DECLARE_WAITQUEUE(wait, current); >+ va_list args; >+ char *tmpbuf; >+ char *buf; >+ int i; >+ unsigned int len; >+ >+ if (!gr_learn_attached) >+ return; >+ >+ tmpbuf = vmalloc(LEARN_BUFFER_SIZE); >+ >+ if (tmpbuf == NULL) >+ return; >+ >+ va_start(args, fmt); >+ len = vsnprintf(tmpbuf, LEARN_BUFFER_SIZE, fmt, args); >+ va_end(args); >+ >+ if (len < 0) >+ len = LEARN_BUFFER_SIZE - 1; >+ >+ buf = vmalloc(len + 1); >+ >+ if (buf == NULL) { >+ vfree(tmpbuf); >+ return; >+ } >+ >+ memcpy(buf, tmpbuf, len); >+ buf[len] = '\0'; >+ vfree(tmpbuf); >+ >+ add_wait_queue(&input_wait, &wait); >+ >+ atomic_inc(&learn_buffer_count); >+ if (atomic_read(&learn_buffer_count) > ((2 * (LEARN_BUFFER_SLOTS - 1)) + 1)) { >+ /* don't sleep under the BKL */ >+// if (unlikely(current->lock_depth >= 0)) { >+ remove_wait_queue(&input_wait, &wait); >+ atomic_dec(&learn_buffer_count); >+ vfree(buf); >+ return; >+// } >+// sleep_on(&input_wait); >+ } >+ >+ if (!gr_acl_is_enabled()) { >+ remove_wait_queue(&input_wait, &wait); >+ atomic_dec(&learn_buffer_count); >+ vfree(buf); >+ return; >+ } >+ >+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) { >+ spin_lock(&learn_buffer_lock[i]); >+ >+ if (learn_buffer_len[i]) { >+ spin_unlock(&learn_buffer_lock[i]); >+ continue; >+ } >+ >+ learn_buffer[i] = buf; >+ >+ learn_buffer_len[i] = len + 1; >+ >+ atomic_inc(&learn_buffer_count); >+ spin_unlock(&learn_buffer_lock[i]); >+ break; >+ } >+ >+ remove_wait_queue(&input_wait, &wait); >+ wake_up_interruptible(&learn_wait); >+ >+ return; >+} >+ >+static int >+open_learn(struct inode *inode, struct file *file) >+{ >+ if (file->f_mode & FMODE_READ && gr_learn_attached) >+ return -EBUSY; >+ else if (file->f_mode & FMODE_READ) >+ gr_learn_attached = 1; >+ >+ return 0; >+} >+ >+static int >+close_learn(struct inode *inode, struct file *file) >+{ >+ if (file->f_mode & FMODE_READ) >+ gr_learn_attached = 0; >+ >+ return 0; >+} >+ >+struct file_operations grsec_fops = { >+ read: read_learn, >+ write: write_grsec_handler, >+ open: open_learn, >+ release: close_learn, >+ poll: poll_learn, >+}; >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl_res.c linux-2.4.22-ppc-dev/grsecurity/gracl_res.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl_res.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl_res.c 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,45 @@ >+/* resource handling routines (c) Brad Spengler 2002, 2003 */ >+ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/gracl.h> >+#include <linux/grinternal.h> >+ >+static const char *restab_log[11] = { >+ "RLIMIT_CPU", >+ "RLIMIT_FSIZE", >+ "RLIMIT_DATA", >+ "RLIMIT_STACK", >+ "RLIMIT_CORE", >+ "RLIMIT_RSS", >+ "RLIMIT_NPROC", >+ "RLIMIT_NOFILE", >+ "RLIMIT_MEMLOCK", >+ "RLIMIT_AS", >+ "RLIMIT_LOCKS" >+}; >+ >+__inline__ void >+gr_log_resource(const struct task_struct *task, >+ const int res, const unsigned long wanted) >+{ >+ if (unlikely(res == RLIMIT_NPROC && >+ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || >+ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))) >+ return; >+ >+ if (unlikely(wanted >= task->rlim[res].rlim_cur && >+ task->rlim[res].rlim_cur != RLIM_INFINITY)) >+ security_alert(GR_RESOURCE_MSG, wanted, restab_log[res], >+ task->rlim[res].rlim_cur, >+ gr_task_fullpath(task), task->comm, >+ task->pid, task->uid, task->euid, >+ task->gid, task->egid, >+ gr_parent_task_fullpath(task), >+ task->p_pptr->comm, >+ task->p_pptr->pid, task->p_pptr->uid, >+ task->p_pptr->euid, task->p_pptr->gid, >+ task->p_pptr->egid); >+ >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl_segv.c linux-2.4.22-ppc-dev/grsecurity/gracl_segv.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl_segv.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl_segv.c 2003-09-14 14:07:41.000000000 +0200 >@@ -0,0 +1,327 @@ >+/* >+ * grsecurity/gracl_segv.c >+ * Copyright Brad Spengler 2002, 2003 >+ * >+ */ >+ >+#include <linux/kernel.h> >+#include <linux/mm.h> >+#include <asm/uaccess.h> >+#include <asm/errno.h> >+#include <asm/mman.h> >+#include <net/sock.h> >+#include <linux/file.h> >+#include <linux/fs.h> >+#include <linux/net.h> >+#include <linux/in.h> >+#include <linux/smp_lock.h> >+#include <linux/slab.h> >+#include <linux/types.h> >+#include <linux/sched.h> >+#include <linux/timer.h> >+#include <linux/gracl.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+static struct crash_uid *uid_set; >+static unsigned short uid_used; >+static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED; >+extern rwlock_t gr_inode_lock; >+extern __inline__ struct acl_subject_label *lookup_acl_subj_label(const ino_t >+ inode, >+ const kdev_t >+ dev, >+ struct >+ acl_role_label >+ *role); >+ >+int >+gr_init_uidset(void) >+{ >+ uid_set = >+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL); >+ uid_used = 0; >+ >+ return uid_set ? 1 : 0; >+} >+ >+void >+gr_free_uidset(void) >+{ >+ if (uid_set) >+ kfree(uid_set); >+ >+ return; >+} >+ >+int >+gr_find_uid(const uid_t uid) >+{ >+ struct crash_uid *tmp = uid_set; >+ uid_t buid; >+ int low = 0, high = uid_used - 1, mid; >+ >+ while (high >= low) { >+ mid = (low + high) >> 1; >+ buid = tmp[mid].uid; >+ if (buid == uid) >+ return mid; >+ if (buid > uid) >+ high = mid - 1; >+ if (buid < uid) >+ low = mid + 1; >+ } >+ >+ return -1; >+} >+ >+static __inline__ void >+gr_insertsort(void) >+{ >+ unsigned short i, j; >+ struct crash_uid index; >+ >+ for (i = 1; i < uid_used; i++) { >+ index = uid_set[i]; >+ j = i; >+ while ((j > 0) && uid_set[j - 1].uid > index.uid) { >+ uid_set[j] = uid_set[j - 1]; >+ j--; >+ } >+ uid_set[j] = index; >+ } >+ >+ return; >+} >+ >+static __inline__ void >+gr_insert_uid(const uid_t uid, const unsigned long expires) >+{ >+ int loc; >+ >+ if (uid_used == GR_UIDTABLE_MAX) >+ return; >+ >+ loc = gr_find_uid(uid); >+ >+ if (loc >= 0) { >+ uid_set[loc].expires = expires; >+ return; >+ } >+ >+ uid_set[uid_used].uid = uid; >+ uid_set[uid_used].expires = expires; >+ uid_used++; >+ >+ gr_insertsort(); >+ >+ return; >+} >+ >+void >+gr_remove_uid(const unsigned short loc) >+{ >+ unsigned short i; >+ >+ for (i = loc + 1; i < uid_used; i++) >+ uid_set[i - i] = uid_set[i]; >+ >+ uid_used--; >+ >+ return; >+} >+ >+int >+gr_check_crash_uid(const uid_t uid) >+{ >+ int loc; >+ >+ if (unlikely(!gr_acl_is_enabled())) >+ return 0; >+ >+ read_lock(&gr_uid_lock); >+ loc = gr_find_uid(uid); >+ read_unlock(&gr_uid_lock); >+ >+ if (loc < 0) >+ return 0; >+ >+ write_lock(&gr_uid_lock); >+ if (time_before_eq(uid_set[loc].expires, jiffies)) >+ gr_remove_uid(loc); >+ else { >+ write_unlock(&gr_uid_lock); >+ return 1; >+ } >+ >+ write_unlock(&gr_uid_lock); >+ return 0; >+} >+ >+static __inline__ int >+proc_is_setxid(const struct task_struct *task) >+{ >+ if (task->uid != task->euid || task->uid != task->suid || >+ task->uid != task->fsuid) >+ return 1; >+ if (task->gid != task->egid || task->gid != task->sgid || >+ task->gid != task->fsgid) >+ return 1; >+ >+ return 0; >+} >+static __inline__ int >+gr_fake_force_sig(int sig, struct task_struct *t) >+{ >+ unsigned long int flags; >+ >+ spin_lock_irqsave(&t->sigmask_lock, flags); >+ if (t->sig == NULL) { >+ spin_unlock_irqrestore(&t->sigmask_lock, flags); >+ return -ESRCH; >+ } >+ >+ if (t->sig->action[sig - 1].sa.sa_handler == SIG_IGN) >+ t->sig->action[sig - 1].sa.sa_handler = SIG_DFL; >+ sigdelset(&t->blocked, sig); >+ recalc_sigpending(t); >+ spin_unlock_irqrestore(&t->sigmask_lock, flags); >+ >+ return send_sig_info(sig, (void *) 1L, t); >+} >+ >+void >+gr_handle_crash(struct task_struct *task, const int sig) >+{ >+ struct acl_subject_label *curr; >+ struct acl_subject_label *curr2; >+ struct task_struct *tsk; >+ >+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL) >+ return; >+ >+ if (unlikely(!gr_acl_is_enabled())) >+ return; >+ >+ curr = task->acl; >+ >+ if (!(curr->resmask & (1 << GR_CRASH_RES))) >+ return; >+ >+ if (time_before_eq(curr->expires, jiffies)) { >+ curr->expires = 0; >+ curr->crashes = 0; >+ } >+ >+ curr->crashes++; >+ >+ if (!curr->expires) >+ curr->expires = jiffies + curr->res[GR_CRASH_RES].rlim_max; >+ >+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && >+ time_after(curr->expires, jiffies)) { >+ if (task->uid && proc_is_setxid(task)) { >+ security_alert(GR_SEGVSTART_ACL_MSG, >+ gr_task_fullpath(task), task->comm, >+ task->pid, task->uid, task->euid, >+ task->gid, task->egid, >+ gr_parent_task_fullpath(task), >+ task->p_pptr->comm, task->p_pptr->pid, >+ task->p_pptr->uid, task->p_pptr->euid, >+ task->p_pptr->gid, task->p_pptr->egid, >+ task->uid, >+ curr->res[GR_CRASH_RES].rlim_max / HZ); >+ write_lock(&gr_uid_lock); >+ gr_insert_uid(task->uid, curr->expires); >+ write_unlock(&gr_uid_lock); >+ curr->expires = 0; >+ curr->crashes = 0; >+ read_lock(&tasklist_lock); >+ for_each_task(tsk) { >+ if (tsk != task && tsk->uid == task->uid) >+ gr_fake_force_sig(SIGKILL, tsk); >+ } >+ read_unlock(&tasklist_lock); >+ } else { >+ security_alert(GR_SEGVNOSUID_ACL_MSG, >+ gr_task_fullpath(task), task->comm, >+ task->pid, task->uid, task->euid, >+ task->gid, task->egid, >+ gr_parent_task_fullpath(task), >+ task->p_pptr->comm, task->p_pptr->pid, >+ task->p_pptr->uid, task->p_pptr->euid, >+ task->p_pptr->gid, task->p_pptr->egid, >+ kdevname(curr->device), curr->inode, >+ curr->res[GR_CRASH_RES].rlim_max / HZ); >+ read_lock(&tasklist_lock); >+ for_each_task(tsk) { >+ if (likely(tsk != task)) { >+ curr2 = tsk->acl; >+ >+ if (curr2->device == curr->device && >+ curr2->inode == curr->inode) >+ gr_fake_force_sig(SIGKILL, tsk); >+ } >+ } >+ read_unlock(&tasklist_lock); >+ } >+ } >+ >+ return; >+} >+ >+int >+gr_check_crash_exec(const struct file *filp) >+{ >+ struct acl_subject_label *curr; >+ >+ if (unlikely(!gr_acl_is_enabled())) >+ return 0; >+ >+ read_lock(&gr_inode_lock); >+ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino, >+ filp->f_dentry->d_inode->i_dev, >+ current->role); >+ read_unlock(&gr_inode_lock); >+ >+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) || >+ (!curr->crashes && !curr->expires)) >+ return 0; >+ >+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) && >+ time_after(curr->expires, jiffies)) >+ return 1; >+ else if (time_before_eq(curr->expires, jiffies)) { >+ curr->crashes = 0; >+ curr->expires = 0; >+ } >+ >+ return 0; >+} >+ >+void >+gr_handle_alertkill(void) >+{ >+ struct acl_subject_label *curracl; >+ __u32 curr_ip; >+ struct task_struct *task; >+ >+ if (unlikely(!gr_acl_is_enabled())) >+ return; >+ >+ curracl = current->acl; >+ curr_ip = current->curr_ip; >+ >+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip && >+ (curr_ip != 0xffffffff)) { >+ read_lock(&tasklist_lock); >+ for_each_task(task) { >+ if (task->curr_ip == curr_ip) >+ gr_fake_force_sig(SIGKILL, task); >+ } >+ read_unlock(&tasklist_lock); >+ } else if (curracl->mode & GR_KILLPROC) >+ gr_fake_force_sig(SIGKILL, current); >+ >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/gracl_shm.c linux-2.4.22-ppc-dev/grsecurity/gracl_shm.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/gracl_shm.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/gracl_shm.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,36 @@ >+/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */ >+ >+#include <linux/kernel.h> >+#include <linux/mm.h> >+#include <linux/sched.h> >+#include <linux/file.h> >+#include <linux/ipc.h> >+#include <linux/gracl.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+int >+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, >+ const time_t shm_createtime, const uid_t cuid, const int shmid) >+{ >+ struct task_struct *task; >+ >+ if (!gr_acl_is_enabled()) >+ return 1; >+ >+ task = find_task_by_pid(shm_cprid); >+ >+ if (unlikely(!task)) >+ task = find_task_by_pid(shm_lapid); >+ >+ if (unlikely(task && ((task->start_time < shm_createtime) || >+ (task->pid == shm_lapid)) && >+ (task->acl->mode & GR_PROTSHM) && >+ (task->acl != current->acl))) { >+ security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid, >+ DEFAULTSECARGS); >+ return 0; >+ } >+ >+ return 1; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_chdir.c linux-2.4.22-ppc-dev/grsecurity/grsec_chdir.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_chdir.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_chdir.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,20 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/fs.h> >+#include <linux/file.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+void >+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR >+ if ((grsec_enable_chdir && grsec_enable_group && >+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir && >+ !grsec_enable_group)) { >+ security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt), >+ DEFAULTSECARGS); >+ } >+#endif >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_chroot.c linux-2.4.22-ppc-dev/grsecurity/grsec_chroot.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_chroot.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_chroot.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,333 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/file.h> >+#include <linux/fs.h> >+#include <linux/types.h> >+#include <linux/grinternal.h> >+ >+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); >+ 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)) { >+ 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 < p->nice) >+ && proc_is_chrooted(current)))) { >+ 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)) { >+ 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); >+ 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); >+ 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); >+ 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)) { >+ 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)) { >+ 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)) { >+ 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)) { >+ 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)) { >+ security_alert(GR_CHMOD_CHROOT_MSG, >+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); >+ return -EPERM; >+ } >+#endif >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_disabled.c linux-2.4.22-ppc-dev/grsecurity/grsec_disabled.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_disabled.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_disabled.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,380 @@ >+/* >+ * when grsecurity is disabled, compile all external functions into nothing >+ */ >+ >+#include <linux/kernel.h> >+#include <linux/config.h> >+#include <linux/sched.h> >+#include <linux/file.h> >+#include <linux/fs.h> >+#include <linux/kdev_t.h> >+#include <linux/net.h> >+#include <linux/in.h> >+#include <linux/ip.h> >+#include <linux/skbuff.h> >+#include <linux/sysctl.h> >+ >+#ifdef CONFIG_SYSCTL >+__u32 >+gr_handle_sysctl(const struct ctl_table * table, __u32 mode) >+{ >+ return mode; >+} >+#endif >+ >+int >+gr_acl_is_enabled(void) >+{ >+ return 0; >+} >+ >+int >+gr_handle_rawio(const struct inode *inode) >+{ >+ return 0; >+} >+ >+void >+gr_acl_handle_psacct(struct task_struct *task, const long code) >+{ >+ return; >+} >+ >+int >+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ return 0; >+} >+ >+int >+gr_handle_mmap(const struct file *filp, const unsigned long prot) >+{ >+ return 0; >+} >+ >+int >+gr_handle_ptrace(struct task_struct *task, const long request) >+{ >+ return 0; >+} >+ >+void >+gr_learn_resource(const struct task_struct *task, >+ const int res, const unsigned long wanted) >+{ >+ return; >+} >+ >+int >+gr_set_acls(const int type) >+{ >+ return 0; >+} >+ >+int >+gr_check_hidden_task(const struct task_struct *tsk) >+{ >+ return 0; >+} >+ >+int >+gr_check_protected_task(const struct task_struct *task) >+{ >+ return 0; >+} >+ >+__inline__ void >+gr_copy_label(struct task_struct *tsk) >+{ >+ return; >+} >+ >+void >+gr_set_pax_flags(struct task_struct *task) >+{ >+ return; >+} >+ >+void >+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ return; >+} >+ >+void >+gr_handle_delete(const ino_t ino, const kdev_t dev) >+{ >+ return; >+} >+ >+void >+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+ return; >+} >+ >+void >+gr_handle_crash(struct task_struct *task, const int sig) >+{ >+ return; >+} >+ >+int >+gr_check_crash_exec(const struct file *filp) >+{ >+ return 0; >+} >+ >+int >+gr_check_crash_uid(const uid_t uid) >+{ >+ return 0; >+} >+ >+int >+gr_handle_rename(struct inode *old_dir, struct inode *new_dir, >+ struct dentry *old_dentry, >+ struct dentry *new_dentry, >+ struct vfsmount *mnt, const __u8 replace) >+{ >+ return 0; >+} >+ >+int >+gr_search_socket(const int family, const int type, const int protocol) >+{ >+ return 1; >+} >+ >+int >+gr_search_connectbind(const int mode, const struct socket *sock, >+ const struct sockaddr_in *addr) >+{ >+ return 1; >+} >+ >+int >+gr_is_capable(const int cap) >+{ >+ return 1; >+} >+ >+void >+gr_handle_alertkill(void) >+{ >+ return; >+} >+ >+__u32 >+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_hidden_file(const struct dentry * dentry, >+ const struct vfsmount * mnt) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt, >+ const int fmode) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt) >+{ >+ return 1; >+} >+ >+int >+gr_acl_handle_mmap(const struct file *file, const unsigned long prot, >+ unsigned int *vm_flags) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_truncate(const struct dentry * dentry, >+ const struct vfsmount * mnt) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_access(const struct dentry * dentry, >+ const struct vfsmount * mnt, const int fmode) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt, >+ mode_t mode) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt, >+ mode_t mode) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt) >+{ >+ return 1; >+} >+ >+void >+grsecurity_init(void) >+{ >+ return; >+} >+ >+__u32 >+gr_acl_handle_mknod(const struct dentry * new_dentry, >+ const struct dentry * parent_dentry, >+ const struct vfsmount * parent_mnt, >+ const int mode) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_mkdir(const struct dentry * new_dentry, >+ const struct dentry * parent_dentry, >+ const struct vfsmount * parent_mnt) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_symlink(const struct dentry * new_dentry, >+ const struct dentry * parent_dentry, >+ const struct vfsmount * parent_mnt, const char *from) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_link(const struct dentry * new_dentry, >+ const struct dentry * parent_dentry, >+ const struct vfsmount * parent_mnt, >+ const struct dentry * old_dentry, >+ const struct vfsmount * old_mnt, const char *to) >+{ >+ return 1; >+} >+ >+int >+gr_acl_handle_rename(const struct dentry *new_dentry, >+ const struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt, >+ const struct dentry *old_dentry, >+ const struct inode *old_parent_inode, >+ const struct vfsmount *old_mnt, const char *newname) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_filldir(const struct dentry * dentry, >+ const struct vfsmount * mnt, const ino_t ino) >+{ >+ return 1; >+} >+ >+int >+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, >+ const time_t shm_createtime, const uid_t cuid, const int shmid) >+{ >+ return 1; >+} >+ >+int >+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr) >+{ >+ return 1; >+} >+ >+int >+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt) >+{ >+ return 1; >+} >+ >+__u32 >+gr_acl_handle_creat(const struct dentry * dentry, >+ const struct dentry * p_dentry, >+ const struct vfsmount * p_mnt, const int fmode, >+ const int imode) >+{ >+ return 1; >+} >+ >+void >+gr_acl_handle_exit(void) >+{ >+ return; >+} >+ >+int >+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot) >+{ >+ return 1; >+} >+ >+void >+gr_set_role_label(const uid_t uid, const gid_t gid) >+{ >+ return; >+} >+ >+int >+gr_acl_handle_procpidmem(const struct task_struct *task) >+{ >+ return 0; >+} >+ >+int >+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb) >+{ >+ return 1; >+} >+ >+int >+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr) >+{ >+ return 1; >+} >+ >+void >+gr_set_kernel_label(struct task_struct *task) >+{ >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_exec.c linux-2.4.22-ppc-dev/grsecurity/grsec_exec.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_exec.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_exec.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,70 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/file.h> >+#include <linux/fs.h> >+#include <linux/types.h> >+#include <linux/grdefs.h> >+#include <linux/grinternal.h> >+#include <linux/capability.h> >+ >+#include <asm/uaccess.h> >+ >+int >+gr_handle_nproc(void) >+{ >+#ifdef CONFIG_GRKERNSEC_EXECVE >+ if (grsec_enable_execve && current->user && >+ (atomic_read(¤t->user->processes) > >+ current->rlim[RLIMIT_NPROC].rlim_cur) && >+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) { >+ security_alert(GR_NPROC_MSG, DEFAULTSECARGS); >+ return -EAGAIN; >+ } >+#endif >+ return 0; >+} >+ >+void >+gr_handle_exec_args(struct linux_binprm *bprm, char **argv) >+{ >+#ifdef CONFIG_GRKERNSEC_EXECLOG >+ char grarg[64] = { 0 }; >+ __u8 execlen = 0; >+ unsigned int i; >+ >+ if (!((grsec_enable_execlog && grsec_enable_group && >+ in_group_p(grsec_audit_gid)) >+ || (grsec_enable_execlog && !grsec_enable_group))) >+ return; >+ >+ if (unlikely(!argv)) >+ goto log; >+ >+ for (i = 0; i < bprm->argc && execlen < 62; i++) { >+ char *p; >+ __u8 len; >+ >+ if (get_user(p, argv + i)) >+ goto log; >+ if (!p) >+ goto log; >+ len = strnlen_user(p, 62 - execlen); >+ if (len > 62 - execlen) >+ len = 62 - execlen; >+ else if (len > 0) >+ len--; >+ if (copy_from_user(grarg + execlen, p, len)) >+ goto log; >+ execlen += len; >+ *(grarg + execlen) = ' '; >+ *(grarg + execlen + 1) = '\0'; >+ execlen++; >+ } >+ >+ log: >+ security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry, >+ bprm->file->f_vfsmnt), >+ grarg, DEFAULTSECARGS); >+#endif >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_fifo.c linux-2.4.22-ppc-dev/grsecurity/grsec_fifo.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_fifo.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_fifo.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,24 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/fs.h> >+#include <linux/file.h> >+#include <linux/grinternal.h> >+ >+int >+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt, >+ const struct dentry *dir, const int flag, const int acc_mode) >+{ >+#ifdef CONFIG_GRKERNSEC_FIFO >+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) && >+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) && >+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) && >+ (current->fsuid != dentry->d_inode->i_uid)) { >+ if (!permission(dentry->d_inode, acc_mode)) >+ security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt), >+ dentry->d_inode->i_uid, >+ dentry->d_inode->i_gid, DEFAULTSECARGS); >+ return -EACCES; >+ } >+#endif >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_fork.c linux-2.4.22-ppc-dev/grsecurity/grsec_fork.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_fork.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_fork.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,14 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+void >+gr_log_forkfail(const int retval) >+{ >+#ifdef CONFIG_GRKERNSEC_FORKFAIL >+ if (grsec_enable_forkfail) >+ security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS); >+#endif >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_init.c linux-2.4.22-ppc-dev/grsecurity/grsec_init.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_init.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_init.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,210 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/mm.h> >+#include <linux/smp_lock.h> >+#include <linux/gracl.h> >+#include <linux/slab.h> >+ >+int grsec_enable_link; >+int grsec_enable_dmesg; >+int grsec_enable_fifo; >+int grsec_enable_execve; >+int grsec_enable_execlog; >+int grsec_enable_signal; >+int grsec_enable_forkfail; >+int grsec_enable_time; >+int grsec_enable_group; >+int grsec_audit_gid; >+int grsec_enable_chdir; >+int grsec_enable_audit_ipc; >+int grsec_enable_mount; >+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_randpid; >+int grsec_enable_randid; >+int grsec_enable_randisn; >+int grsec_enable_randsrc; >+int grsec_enable_randrpc; >+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]; >+extern struct gr_arg *gr_usermode; >+extern unsigned char *gr_system_salt; >+extern unsigned char *gr_system_sum; >+ >+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; >+ } >+ } >+ } >+ >+ /* allocate memory for authentication structure */ >+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL); >+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL); >+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL); >+ >+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) { >+ panic("Unable to allocate grsecurity authentication structure"); >+ return; >+ } >+ >+#ifndef CONFIG_GRKERNSEC_SYSCTL >+ grsec_lock = 1; >+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP >+ grsec_enable_group = 1; >+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID; >+#endif >+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR >+ grsec_enable_chdir = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC >+ grsec_enable_audit_ipc = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT >+ grsec_enable_mount = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_LINK >+ grsec_enable_link = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_DMESG >+ grsec_enable_dmesg = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_FIFO >+ grsec_enable_fifo = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_EXECVE >+ grsec_enable_execve = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_EXECLOG >+ grsec_enable_execlog = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_SIGNAL >+ grsec_enable_signal = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_FORKFAIL >+ grsec_enable_forkfail = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_TIME >+ grsec_enable_time = 1; >+#endif >+#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_RANDPID >+ grsec_enable_randpid = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDID >+ grsec_enable_randid = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDISN >+ grsec_enable_randisn = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDSRC >+ grsec_enable_randsrc = 1; >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDRPC >+ grsec_enable_randrpc = 1; >+#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 -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_ipc.c linux-2.4.22-ppc-dev/grsecurity/grsec_ipc.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_ipc.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_ipc.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,81 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/types.h> >+#include <linux/ipc.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+void >+gr_log_msgget(const int ret, const int msgflg) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC >+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && >+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && >+ !grsec_enable_group)) && (ret >= 0) >+ && (msgflg & IPC_CREAT)) >+ security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS); >+#endif >+ return; >+} >+ >+void >+gr_log_msgrm(const uid_t uid, const uid_t cuid) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC >+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && >+ grsec_enable_audit_ipc) || >+ (grsec_enable_audit_ipc && !grsec_enable_group)) >+ security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS); >+#endif >+ return; >+} >+ >+void >+gr_log_semget(const int err, const int semflg) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC >+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && >+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && >+ !grsec_enable_group)) && (err >= 0) >+ && (semflg & IPC_CREAT)) >+ security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS); >+#endif >+ return; >+} >+ >+void >+gr_log_semrm(const uid_t uid, const uid_t cuid) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC >+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && >+ grsec_enable_audit_ipc) || >+ (grsec_enable_audit_ipc && !grsec_enable_group)) >+ security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS); >+#endif >+ return; >+} >+ >+void >+gr_log_shmget(const int err, const int shmflg, const size_t size) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC >+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) && >+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc && >+ !grsec_enable_group)) && (err >= 0) >+ && (shmflg & IPC_CREAT)) >+ security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS); >+#endif >+ return; >+} >+ >+void >+gr_log_shmrm(const uid_t uid, const uid_t cuid) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC >+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) && >+ grsec_enable_audit_ipc) || >+ (grsec_enable_audit_ipc && !grsec_enable_group)) >+ security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS); >+#endif >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_link.c linux-2.4.22-ppc-dev/grsecurity/grsec_link.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_link.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_link.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,41 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/fs.h> >+#include <linux/file.h> >+#include <linux/grinternal.h> >+ >+int >+gr_handle_follow_link(const struct inode *parent, >+ const struct inode *inode, >+ const struct dentry *dentry, const struct vfsmount *mnt) >+{ >+#ifdef CONFIG_GRKERNSEC_LINK >+ if (grsec_enable_link && S_ISLNK(inode->i_mode) && >+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) && >+ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) { >+ security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt), >+ inode->i_uid, inode->i_gid, DEFAULTSECARGS); >+ return -EACCES; >+ } >+#endif >+ return 0; >+} >+ >+int >+gr_handle_hardlink(const struct dentry *dentry, >+ const struct vfsmount *mnt, >+ struct inode *inode, const int mode, const char *to) >+{ >+#ifdef CONFIG_GRKERNSEC_LINK >+ if (grsec_enable_link && current->fsuid != inode->i_uid && >+ (!S_ISREG(mode) || (mode & S_ISUID) || >+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) || >+ (permission(inode, MAY_READ | MAY_WRITE))) && >+ !capable(CAP_FOWNER) && current->uid) { >+ security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt), >+ inode->i_uid, inode->i_gid, to, DEFAULTSECARGS); >+ return -EPERM; >+ } >+#endif >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_mem.c linux-2.4.22-ppc-dev/grsecurity/grsec_mem.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_mem.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_mem.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,54 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/mm.h> >+#include <linux/grinternal.h> >+ >+void >+gr_handle_ioperm(void) >+{ >+ security_alert(GR_IOPERM_MSG, DEFAULTSECARGS); >+ return; >+} >+ >+void >+gr_handle_iopl(void) >+{ >+ security_alert(GR_IOPL_MSG, DEFAULTSECARGS); >+ return; >+} >+ >+void >+gr_handle_mem_write(void) >+{ >+ security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS); >+ return; >+} >+ >+void >+gr_handle_kmem_write(void) >+{ >+ security_alert(GR_KMEM_MSG, DEFAULTSECARGS); >+ return; >+} >+ >+void >+gr_handle_open_port(void) >+{ >+ security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS); >+ return; >+} >+ >+int >+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma) >+{ >+ if (offset < __pa(high_memory) && >+ (pgprot_val(vma->vm_page_prot) & PROT_WRITE) && >+ !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) && >+ !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) { >+ security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS); >+ return -EPERM; >+ } else if (offset < __pa(high_memory)) >+ vma->vm_flags &= ~VM_MAYWRITE; >+ >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_mount.c linux-2.4.22-ppc-dev/grsecurity/grsec_mount.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_mount.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_mount.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,34 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+void >+gr_log_remount(const char *devname, const int retval) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT >+ if (grsec_enable_mount && (retval >= 0)) >+ security_audit(GR_REMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS); >+#endif >+ return; >+} >+ >+void >+gr_log_unmount(const char *devname, const int retval) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT >+ if (grsec_enable_mount && (retval >= 0)) >+ security_audit(GR_UNMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS); >+#endif >+ return; >+} >+ >+void >+gr_log_mount(const char *from, const char *to, const int retval) >+{ >+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT >+ if (grsec_enable_mount && (retval >= 0)) >+ security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS); >+#endif >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_rand.c linux-2.4.22-ppc-dev/grsecurity/grsec_rand.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_rand.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_rand.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,36 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/smp_lock.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+extern int last_pid; >+ >+int >+gr_random_pid(spinlock_t * pid_lock) >+{ >+#ifdef CONFIG_GRKERNSEC_RANDPID >+ struct task_struct *p; >+ int pid; >+ >+ if (grsec_enable_randpid && current->fs->root) { >+ read_lock(&tasklist_lock); >+ spin_lock(pid_lock); >+ >+ repeater: >+ >+ pid = 1 + (get_random_long() % PID_MAX); >+ >+ for_each_task(p) { >+ if (p->pid == pid || p->pgrp == pid || >+ p->tgid == pid || p->session == pid) >+ goto repeater; >+ } >+ last_pid = pid; >+ spin_unlock(pid_lock); >+ read_unlock(&tasklist_lock); >+ return pid; >+ } >+#endif >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_sig.c linux-2.4.22-ppc-dev/grsecurity/grsec_sig.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_sig.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_sig.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,47 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/grinternal.h> >+ >+void >+gr_log_signal(const int sig, const struct task_struct *t) >+{ >+#ifdef CONFIG_GRKERNSEC_SIGNAL >+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) || >+ (sig == SIGABRT) || (sig == SIGBUS))) { >+ if (t->pid == current->pid) { >+ security_alert_good(GR_UNISIGLOG_MSG, sig, >+ DEFAULTSECARGS); >+ } else { >+ security_alert_good(GR_DUALSIGLOG_MSG, sig, >+ gr_task_fullpath(t), t->comm, >+ t->pid, t->uid, t->euid, t->gid, >+ t->egid, gr_parent_task_fullpath(t), >+ t->p_pptr->comm, >+ t->p_pptr->pid, t->p_pptr->uid, >+ t->p_pptr->euid, t->p_pptr->gid, >+ t->p_pptr->egid, DEFAULTSECARGS); >+ } >+ } >+#endif >+ return; >+} >+ >+int >+gr_handle_signal(const struct task_struct *p, const int sig) >+{ >+#ifdef CONFIG_GRKERNSEC >+ if (current->pid > 1 && gr_check_protected_task(p)) { >+ security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath(p), >+ p->comm, p->pid, p->uid, >+ p->euid, p->gid, p->egid, >+ gr_parent_task_fullpath(p), p->p_pptr->comm, >+ p->p_pptr->pid, p->p_pptr->uid, >+ p->p_pptr->euid, p->p_pptr->gid, >+ p->p_pptr->egid, DEFAULTSECARGS); >+ return -EPERM; >+ } else if (gr_pid_is_chrooted(p)) { >+ return -EPERM; >+ } >+#endif >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_sock.c linux-2.4.22-ppc-dev/grsecurity/grsec_sock.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_sock.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_sock.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,123 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/file.h> >+#include <linux/net.h> >+#include <net/sock.h> >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+#include <linux/gracl.h> >+ >+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)) { >+ 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)) { >+ 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)) { >+ security_alert(GR_CONNECT_MSG, DEFAULTSECARGS); >+ return -EACCES; >+ } >+#endif >+ return 0; >+} >+ >+__u32 >+gr_cap_rtnetlink(void) >+{ >+#ifdef CONFIG_GRKERNSEC >+ if (!gr_acl_is_enabled()) >+ return current->cap_effective; >+ else >+ return (current->cap_effective & ~(current->acl->cap_lower)); >+#else >+ return current->cap_effective; >+#endif >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_sysctl.c linux-2.4.22-ppc-dev/grsecurity/grsec_sysctl.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_sysctl.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_sysctl.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,16 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/sysctl.h> >+#include <linux/grinternal.h> >+ >+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)) { >+ security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS); >+ return -EACCES; >+ } >+#endif >+ return 0; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_time.c linux-2.4.22-ppc-dev/grsecurity/grsec_time.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_time.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_time.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,13 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/grinternal.h> >+ >+void >+gr_log_timechange(void) >+{ >+#ifdef CONFIG_GRKERNSEC_TIME >+ if (grsec_enable_time) >+ security_alert_good(GR_TIME_MSG, DEFAULTSECARGS); >+#endif >+ return; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsec_tpe.c linux-2.4.22-ppc-dev/grsecurity/grsec_tpe.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsec_tpe.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsec_tpe.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,35 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/file.h> >+#include <linux/fs.h> >+#include <linux/grinternal.h> >+ >+extern int gr_acl_tpe_check(void); >+ >+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)) || gr_acl_tpe_check()) && >+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) || >+ (inode->i_mode & S_IWOTH))))) { >+ 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))) { >+ security_alert(GR_EXEC_TPE_MSG, >+ gr_to_filename(file->f_dentry, file->f_vfsmnt), >+ DEFAULTSECARGS); >+ return 0; >+ } >+#endif >+#endif >+ return 1; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/grsum.c linux-2.4.22-ppc-dev/grsecurity/grsum.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/grsum.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/grsum.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,59 @@ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/mm.h> >+#include <asm/scatterlist.h> >+#include <linux/crypto.h> >+#include <linux/gracl.h> >+ >+ >+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE) >+#error "crypto and sha256 must be built into the kernel" >+#endif >+ >+int >+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum) >+{ >+ char *p; >+ struct crypto_tfm *tfm; >+ unsigned char temp_sum[GR_SHA_LEN]; >+ struct scatterlist sg[2]; >+ volatile int retval = 0; >+ volatile int dummy = 0; >+ unsigned int i; >+ >+ tfm = crypto_alloc_tfm("sha256", 0); >+ if (tfm == NULL) { >+ /* should never happen, since sha256 should be built in */ >+ return 1; >+ } >+ >+ crypto_digest_init(tfm); >+ >+ p = salt; >+ sg[0].page = virt_to_page(p); >+ sg[0].offset = ((long) p & ~PAGE_MASK); >+ sg[0].length = GR_SALT_LEN; >+ >+ crypto_digest_update(tfm, sg, 1); >+ >+ p = entry->pw; >+ sg[0].page = virt_to_page(p); >+ sg[0].offset = ((long) p & ~PAGE_MASK); >+ sg[0].length = strlen(entry->pw); >+ >+ crypto_digest_update(tfm, sg, 1); >+ >+ crypto_digest_final(tfm, temp_sum); >+ >+ memset(entry->pw, 0, GR_PW_LEN); >+ >+ for (i = 0; i < GR_SHA_LEN; i++) >+ if (sum[i] != temp_sum[i]) >+ retval = 1; >+ else >+ dummy = 1; // waste a cycle >+ >+ crypto_free_tfm(tfm); >+ >+ return retval; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/grsecurity/obsd_rand.c linux-2.4.22-ppc-dev/grsecurity/obsd_rand.c >--- linux-2.4.22-ppc-dev.orig/grsecurity/obsd_rand.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/grsecurity/obsd_rand.c 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,195 @@ >+ >+/* >+ * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff. >+ * >+ * Version 1.89, last modified 19-Sep-99 >+ * >+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. >+ * All rights reserved. >+ * >+ * Copyright 1998 Niels Provos <provos@citi.umich.edu> >+ * All rights reserved. >+ * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using >+ * such a mathematical system to generate more random (yet non-repeating) >+ * ids to solve the resolver/named problem. But Niels designed the >+ * actual system based on the constraints. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer, >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * 3. All advertising materials mentioning features or use of this software >+ * must display the following acknowledgement: >+ * This product includes software developed by Niels Provos. >+ * 4. The name of the author may not be used to endorse or promote products >+ * derived from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR >+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES >+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. >+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, >+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT >+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, >+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY >+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include <linux/kernel.h> >+#include <linux/sched.h> >+#include <linux/timer.h> >+#include <linux/smp_lock.h> >+#include <linux/random.h> >+#include <linux/grsecurity.h> >+ >+#define RU_OUT 180 >+#define RU_MAX 30000 >+#define RU_GEN 2 >+#define RU_N 32749 >+#define RU_AGEN 7 >+#define RU_M 31104 >+#define PFAC_N 3 >+const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 }; >+ >+static __u16 ru_x; >+static __u16 ru_seed, ru_seed2; >+static __u16 ru_a, ru_b; >+static __u16 ru_g; >+static __u16 ru_counter = 0; >+static __u16 ru_msb = 0; >+static unsigned long ru_reseed = 0; >+static __u32 tmp; >+ >+#define TCP_RNDISS_ROUNDS 15 >+#define TCP_RNDISS_OUT 7200 >+#define TCP_RNDISS_MAX 30000 >+ >+static __u8 tcp_rndiss_sbox[NR_CPUS][128]; >+static __u16 tcp_rndiss_msb[NR_CPUS]; >+static __u16 tcp_rndiss_cnt[NR_CPUS]; >+static unsigned long tcp_rndiss_reseed[NR_CPUS]; >+ >+static __u16 pmod(__u16, __u16, __u16); >+static void ip_initid(void); >+__u16 ip_randomid(void); >+ >+static __u16 >+pmod(__u16 gen, __u16 exp, __u16 mod) >+{ >+ __u16 s, t, u; >+ >+ s = 1; >+ t = gen; >+ u = exp; >+ >+ while (u) { >+ if (u & 1) >+ s = (s * t) % mod; >+ u >>= 1; >+ t = (t * t) % mod; >+ } >+ return (s); >+} >+ >+static void >+ip_initid(void) >+{ >+ __u16 j, i; >+ int noprime = 1; >+ >+ ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M; >+ >+ ru_seed = (tmp >> 16) & 0x7FFF; >+ ru_seed2 = get_random_long() & 0x7FFF; >+ >+ ru_b = ((tmp = get_random_long()) & 0xfffe) | 1; >+ ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M); >+ while (ru_b % 3 == 0) >+ ru_b += 2; >+ >+ j = (tmp = get_random_long()) % RU_N; >+ tmp = tmp >> 16; >+ >+ while (noprime) { >+ for (i = 0; i < PFAC_N; i++) >+ if (j % pfacts[i] == 0) >+ break; >+ >+ if (i >= PFAC_N) >+ noprime = 0; >+ else >+ j = (j + 1) % RU_N; >+ } >+ >+ ru_g = pmod(RU_GEN, j, RU_N); >+ ru_counter = 0; >+ >+ ru_reseed = xtime.tv_sec + RU_OUT; >+ ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; >+} >+ >+__u16 >+ip_randomid(void) >+{ >+ int i, n; >+ >+ if (ru_counter >= RU_MAX || time_after(xtime.tv_sec, ru_reseed)) >+ ip_initid(); >+ >+ if (!tmp) >+ tmp = get_random_long(); >+ >+ n = tmp & 0x3; >+ tmp = tmp >> 2; >+ if (ru_counter + n >= RU_MAX) >+ ip_initid(); >+ for (i = 0; i <= n; i++) >+ ru_x = (ru_a * ru_x + ru_b) % RU_M; >+ ru_counter += i; >+ >+ return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb); >+} >+ >+__u16 >+tcp_rndiss_encrypt(__u16 val) >+{ >+ __u16 sum = 0, i; >+ int cpu = smp_processor_id(); >+ >+ for (i = 0; i < TCP_RNDISS_ROUNDS; i++) { >+ sum += 0x79b9; >+ val ^= ((__u16) tcp_rndiss_sbox[cpu][(val ^ sum) ^ 0x7f]) << 7; >+ val = ((val & 0xff) << 7) | (val >> 8); >+ } >+ >+ return val; >+} >+ >+static void >+tcp_rndiss_init(void) >+{ >+ int cpu = smp_processor_id(); >+ >+ get_random_bytes(tcp_rndiss_sbox[cpu], sizeof (tcp_rndiss_sbox)); >+ tcp_rndiss_reseed[cpu] = xtime.tv_sec + TCP_RNDISS_OUT; >+ tcp_rndiss_msb[cpu] = tcp_rndiss_msb[cpu] == 0x8000 ? 0 : 0x8000; >+ tcp_rndiss_cnt[cpu] = 0; >+} >+ >+__u32 >+ip_randomisn(void) >+{ >+ int cpu = smp_processor_id(); >+ >+ if (tcp_rndiss_cnt[cpu] >= TCP_RNDISS_MAX || >+ time_after(xtime.tv_sec, tcp_rndiss_reseed[cpu])) >+ tcp_rndiss_init(); >+ >+ return (((tcp_rndiss_encrypt(tcp_rndiss_cnt[cpu]++) | >+ tcp_rndiss_msb[cpu]) << 16) | (get_random_long() & 0x7fff)); >+} >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-alpha/a.out.h linux-2.4.22-ppc-dev/include/asm-alpha/a.out.h >--- linux-2.4.22-ppc-dev.orig/include/asm-alpha/a.out.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-alpha/a.out.h 2003-09-14 14:07:42.000000000 +0200 >@@ -98,7 +98,7 @@ > set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \ > ? ADDR_LIMIT_32BIT : 0) | PER_OSF4)) > >-#define STACK_TOP \ >+#define __STACK_TOP \ > (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL) > > #endif >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-alpha/elf.h linux-2.4.22-ppc-dev/include/asm-alpha/elf.h >--- linux-2.4.22-ppc-dev.orig/include/asm-alpha/elf.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-alpha/elf.h 2003-09-14 14:07:42.000000000 +0200 >@@ -41,6 +41,18 @@ > > #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) > >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL) >+ >+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28) >+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28) >+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19) >+#endif >+ >+ > /* $0 is set by ld.so to a pointer to a function which might be > registered using atexit. This provides a mean for the dynamic > linker to call DT_FINI functions for shared libraries that have >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-alpha/mman.h linux-2.4.22-ppc-dev/include/asm-alpha/mman.h >--- linux-2.4.22-ppc-dev.orig/include/asm-alpha/mman.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-alpha/mman.h 2003-09-14 14:07:42.000000000 +0200 >@@ -24,6 +24,10 @@ > #define MAP_LOCKED 0x8000 /* lock the mapping */ > #define MAP_NORESERVE 0x10000 /* don't check for reservations */ > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+#define MAP_MIRROR 0x20000 >+#endif >+ > #define MS_ASYNC 1 /* sync memory asynchronously */ > #define MS_SYNC 2 /* synchronous memory sync */ > #define MS_INVALIDATE 4 /* invalidate the caches */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-alpha/pgtable.h linux-2.4.22-ppc-dev/include/asm-alpha/pgtable.h >--- linux-2.4.22-ppc-dev.orig/include/asm-alpha/pgtable.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-alpha/pgtable.h 2003-09-14 14:07:42.000000000 +0200 >@@ -96,6 +96,17 @@ > #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS) > #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) > #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW) >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+#define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE) >+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE) >+#define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE) >+#else >+#define PAGE_SHARED_NOEXEC PAGE_SHARED >+#define PAGE_COPY_NOEXEC PAGE_COPY >+#define PAGE_READONLY_NOEXEC PAGE_READONLY >+#endif >+ > #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE) > > #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x)) >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/a.out.h linux-2.4.22-ppc-dev/include/asm-i386/a.out.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/a.out.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/a.out.h 2003-09-14 14:07:42.000000000 +0200 >@@ -19,7 +19,11 @@ > > #ifdef __KERNEL__ > >-#define STACK_TOP TASK_SIZE >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+#define __STACK_TOP ((current->flags & PF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE) >+#else >+#define __STACK_TOP TASK_SIZE >+#endif > > #endif > >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/desc.h linux-2.4.22-ppc-dev/include/asm-i386/desc.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/desc.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/desc.h 2003-09-14 14:07:42.000000000 +0200 >@@ -46,7 +46,8 @@ > }; > > extern struct desc_struct gdt_table[]; >-extern struct desc_struct *idt, *gdt; >+extern struct desc_struct gdt_table2[]; >+extern struct desc_struct *idt, *gdt, *gdt2; > > struct Xgt_desc_struct { > unsigned short size; >@@ -55,6 +56,7 @@ > > #define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2)) > #define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2)) >+#define gdt_descr2 (*(struct Xgt_desc_struct *)((char *)&gdt2 - 2)) > > #define load_TR(n) __asm__ __volatile__("ltr %%ax"::"a" (__TSS(n)<<3)) > >@@ -67,6 +69,7 @@ > extern struct desc_struct default_ldt[]; > extern void set_intr_gate(unsigned int irq, void * addr); > extern void set_ldt_desc(unsigned int n, void *addr, unsigned int size); >+extern void __set_ldt_desc(unsigned int n, void *addr, unsigned int size); > extern void set_tss_desc(unsigned int n, void *addr); > > static inline void clear_LDT(void) >@@ -94,6 +97,21 @@ > __load_LDT(cpu); > } > >+static inline void _load_LDT (struct mm_struct *mm) >+{ >+ int cpu = smp_processor_id(); >+ void *segments = mm->context.segments; >+ int count = LDT_ENTRIES; >+ >+ if (!segments) { >+ segments = &default_ldt[0]; >+ count = 5; >+ } >+ >+ __set_ldt_desc(cpu, segments, count); >+ __load_LDT(cpu); >+} >+ > #endif /* !__ASSEMBLY__ */ > > #endif >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/elf.h linux-2.4.22-ppc-dev/include/asm-i386/elf.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/elf.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/elf.h 2003-09-14 14:07:42.000000000 +0200 >@@ -55,7 +55,22 @@ > the loader. We need to make sure that it is out of the way of the program > that it will "exec", and that there is sufficient room for the brk. */ > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+#define ELF_ET_DYN_BASE ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3*2:TASK_SIZE/3*2) >+#else > #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+#define PAX_ELF_ET_DYN_BASE(tsk) 0x08048000UL >+ >+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_MMAP_LEN(tsk) 16 >+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_EXEC_LEN(tsk) 16 >+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->flags & PF_PAX_SEGMEXEC ? 15 : 16) >+#endif > > /* Wow, the "main" arch needs arch dependent functions too.. :) */ > >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/hw_irq.h linux-2.4.22-ppc-dev/include/asm-i386/hw_irq.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/hw_irq.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/hw_irq.h 2003-09-14 14:07:42.000000000 +0200 >@@ -128,6 +128,7 @@ > asmlinkage void x(void); \ > asmlinkage void call_##x(void); \ > __asm__( \ >+"\n .text" \ > "\n"__ALIGN_STR"\n" \ > SYMBOL_NAME_STR(x) ":\n\t" \ > "pushl $"#v"-256\n\t" \ >@@ -141,6 +142,7 @@ > asmlinkage void x(struct pt_regs * regs); \ > asmlinkage void call_##x(void); \ > __asm__( \ >+"\n .text" \ > "\n"__ALIGN_STR"\n" \ > SYMBOL_NAME_STR(x) ":\n\t" \ > "pushl $"#v"-256\n\t" \ >@@ -155,6 +157,7 @@ > #define BUILD_COMMON_IRQ() \ > asmlinkage void call_do_IRQ(void); \ > __asm__( \ >+ "\n .text" \ > "\n" __ALIGN_STR"\n" \ > "common_interrupt:\n\t" \ > SAVE_ALL \ >@@ -175,6 +178,7 @@ > #define BUILD_IRQ(nr) \ > asmlinkage void IRQ_NAME(nr); \ > __asm__( \ >+"\n .text" \ > "\n"__ALIGN_STR"\n" \ > SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ > "pushl $"#nr"-256\n\t" \ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/mman.h linux-2.4.22-ppc-dev/include/asm-i386/mman.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/mman.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/mman.h 2003-09-14 14:07:42.000000000 +0200 >@@ -18,6 +18,10 @@ > #define MAP_LOCKED 0x2000 /* pages are locked */ > #define MAP_NORESERVE 0x4000 /* don't check for reservations */ > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+#define MAP_MIRROR 0x8000 >+#endif >+ > #define MS_ASYNC 1 /* sync memory asynchronously */ > #define MS_INVALIDATE 2 /* invalidate the caches */ > #define MS_SYNC 4 /* synchronous memory sync */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/page.h linux-2.4.22-ppc-dev/include/asm-i386/page.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/page.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/page.h 2003-09-14 14:07:42.000000000 +0200 >@@ -78,7 +78,7 @@ > * and CONFIG_HIGHMEM64G options in the kernel configuration. > */ > >-#define __PAGE_OFFSET (0xC0000000) >+#include <asm/page_offset.h> > > /* > * This much address space is reserved for vmalloc() and iomap() >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/page_offset.h linux-2.4.22-ppc-dev/include/asm-i386/page_offset.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/page_offset.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/asm-i386/page_offset.h 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,2 @@ >+#define __KERNEL_TEXT_OFFSET (0xC0400000) >+#define __PAGE_OFFSET (0xC0000000) >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/pgtable.h linux-2.4.22-ppc-dev/include/asm-i386/pgtable.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/pgtable.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/pgtable.h 2003-09-14 14:07:42.000000000 +0200 >@@ -205,6 +205,16 @@ > #define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) > #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) > >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+#define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED) >+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) >+#define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) >+#else >+#define PAGE_SHARED_NOEXEC PAGE_SHARED >+#define PAGE_COPY_NOEXEC PAGE_COPY >+#define PAGE_READONLY_NOEXEC PAGE_READONLY >+#endif >+ > #define __PAGE_KERNEL \ > (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) > #define __PAGE_KERNEL_NOCACHE \ >@@ -237,18 +247,18 @@ > * This is the closest we can get.. > */ > #define __P000 PAGE_NONE >-#define __P001 PAGE_READONLY >-#define __P010 PAGE_COPY >-#define __P011 PAGE_COPY >+#define __P001 PAGE_READONLY_NOEXEC >+#define __P010 PAGE_COPY_NOEXEC >+#define __P011 PAGE_COPY_NOEXEC > #define __P100 PAGE_READONLY > #define __P101 PAGE_READONLY > #define __P110 PAGE_COPY > #define __P111 PAGE_COPY > > #define __S000 PAGE_NONE >-#define __S001 PAGE_READONLY >-#define __S010 PAGE_SHARED >-#define __S011 PAGE_SHARED >+#define __S001 PAGE_READONLY_NOEXEC >+#define __S010 PAGE_SHARED_NOEXEC >+#define __S011 PAGE_SHARED_NOEXEC > #define __S100 PAGE_READONLY > #define __S101 PAGE_READONLY > #define __S110 PAGE_SHARED >@@ -324,7 +334,7 @@ > ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) > > /* to find an entry in a page-table-directory. */ >-#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) >+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) > > #define __pgd_offset(address) pgd_index(address) > >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/processor.h linux-2.4.22-ppc-dev/include/asm-i386/processor.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/processor.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/processor.h 2003-09-14 14:07:42.000000000 +0200 >@@ -261,10 +261,19 @@ > */ > #define TASK_SIZE (PAGE_OFFSET) > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+#define SEGMEXEC_TASK_SIZE ((PAGE_OFFSET) / 2) >+#endif >+ > /* This decides where the kernel will search for a free chunk of vm > * space during mmap's. > */ >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+#define TASK_UNMAPPED_BASE ((current->flags & PF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE/3:TASK_SIZE/3) >+#else > #define TASK_UNMAPPED_BASE (TASK_SIZE / 3) >+#endif > > /* > * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-i386/system.h linux-2.4.22-ppc-dev/include/asm-i386/system.h >--- linux-2.4.22-ppc-dev.orig/include/asm-i386/system.h 2003-09-14 14:03:12.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-i386/system.h 2003-09-14 14:07:42.000000000 +0200 >@@ -12,6 +12,8 @@ > struct task_struct; /* one of the stranger aspects of C forward declarations.. */ > extern void FASTCALL(__switch_to(struct task_struct *prev, struct task_struct *next)); > >+void pax_switch_segments(struct task_struct *); >+ > #define prepare_to_switch() do { } while(0) > #define switch_to(prev,next,last) do { \ > asm volatile("pushl %%esi\n\t" \ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-parisc/a.out.h linux-2.4.22-ppc-dev/include/asm-parisc/a.out.h >--- linux-2.4.22-ppc-dev.orig/include/asm-parisc/a.out.h 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-parisc/a.out.h 2003-09-14 14:07:42.000000000 +0200 >@@ -22,7 +22,7 @@ > /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc. > * prumpf */ > >-#define STACK_TOP TASK_SIZE >+#define __STACK_TOP TASK_SIZE > > #endif > >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-parisc/elf.h linux-2.4.22-ppc-dev/include/asm-parisc/elf.h >--- linux-2.4.22-ppc-dev.orig/include/asm-parisc/elf.h 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-parisc/elf.h 2003-09-14 14:07:42.000000000 +0200 >@@ -135,6 +135,17 @@ > > #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000) > >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL >+ >+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_MMAP_LEN(tsk) 16 >+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_EXEC_LEN(tsk) 16 >+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_STACK_LEN(tsk) 16 >+#endif >+ > /* This yields a mask that user programs can use to figure out what > instruction set this CPU supports. This could be done in user space, > but it's not easy, and we've already done it here. */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-parisc/mman.h linux-2.4.22-ppc-dev/include/asm-parisc/mman.h >--- linux-2.4.22-ppc-dev.orig/include/asm-parisc/mman.h 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-parisc/mman.h 2003-09-14 14:07:42.000000000 +0200 >@@ -18,6 +18,10 @@ > #define MAP_NORESERVE 0x4000 /* don't check for reservations */ > #define MAP_GROWSDOWN 0x8000 /* stack-like segment */ > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+#define MAP_MIRROR 0x0400 >+#endif >+ > #define MS_SYNC 1 /* synchronous memory sync */ > #define MS_ASYNC 2 /* sync memory asynchronously */ > #define MS_INVALIDATE 4 /* invalidate the caches */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-parisc/pgtable.h linux-2.4.22-ppc-dev/include/asm-parisc/pgtable.h >--- linux-2.4.22-ppc-dev.orig/include/asm-parisc/pgtable.h 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-parisc/pgtable.h 2003-09-14 14:07:42.000000000 +0200 >@@ -167,6 +167,17 @@ > #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED) > #define PAGE_COPY PAGE_EXECREAD > #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+#define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED) >+#define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) >+#define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED) >+#else >+#define PAGE_SHARED_NOEXEC PAGE_SHARED >+#define PAGE_COPY_NOEXEC PAGE_COPY >+#define PAGE_READONLY_NOEXEC PAGE_READONLY >+#endif >+ > #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) > #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED) > #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-ppc/a.out.h linux-2.4.22-ppc-dev/include/asm-ppc/a.out.h >--- linux-2.4.22-ppc-dev.orig/include/asm-ppc/a.out.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-ppc/a.out.h 2003-09-14 14:07:42.000000000 +0200 >@@ -2,7 +2,7 @@ > #define __PPC_A_OUT_H__ > > /* grabbed from the intel stuff */ >-#define STACK_TOP TASK_SIZE >+#define __STACK_TOP TASK_SIZE > > > struct exec >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-ppc/elf.h linux-2.4.22-ppc-dev/include/asm-ppc/elf.h >--- linux-2.4.22-ppc-dev.orig/include/asm-ppc/elf.h 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-ppc/elf.h 2003-09-14 14:07:42.000000000 +0200 >@@ -46,6 +46,17 @@ > > #define ELF_ET_DYN_BASE (0x08000000) > >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000000UL >+ >+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_MMAP_LEN(tsk) 15 >+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_EXEC_LEN(tsk) 15 >+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_STACK_LEN(tsk) 15 >+#endif >+ > #define USE_ELF_CORE_DUMP > #define ELF_EXEC_PAGESIZE 4096 > >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-ppc/mman.h linux-2.4.22-ppc-dev/include/asm-ppc/mman.h >--- linux-2.4.22-ppc-dev.orig/include/asm-ppc/mman.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-ppc/mman.h 2003-09-14 14:07:42.000000000 +0200 >@@ -19,6 +19,10 @@ > #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ > #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+#define MAP_MIRROR 0x0200 >+#endif >+ > #define MS_ASYNC 1 /* sync memory asynchronously */ > #define MS_INVALIDATE 2 /* invalidate the caches */ > #define MS_SYNC 4 /* synchronous memory sync */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-ppc/pgtable.h linux-2.4.22-ppc-dev/include/asm-ppc/pgtable.h >--- linux-2.4.22-ppc-dev.orig/include/asm-ppc/pgtable.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-ppc/pgtable.h 2003-09-14 14:07:42.000000000 +0200 >@@ -335,6 +335,16 @@ > #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER) > #define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC) > >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED) >+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED) >+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED) >+#else >+# define PAGE_SHARED_NOEXEC PAGE_SHARED >+# define PAGE_COPY_NOEXEC PAGE_COPY >+# define PAGE_READONLY_NOEXEC PAGE_READONLY >+#endif >+ > #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) > #define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_SHARED) > #define PAGE_KERNEL_CI __pgprot(_PAGE_IO) >@@ -346,21 +356,21 @@ > * This is the closest we can get.. > */ > #define __P000 PAGE_NONE >-#define __P001 PAGE_READONLY_X >-#define __P010 PAGE_COPY >-#define __P011 PAGE_COPY_X >-#define __P100 PAGE_READONLY >+#define __P001 PAGE_READONLY_NOEXEC >+#define __P010 PAGE_COPY_NOEXEC >+#define __P011 PAGE_COPY_NOEXEC >+#define __P100 PAGE_READONLY_X > #define __P101 PAGE_READONLY_X >-#define __P110 PAGE_COPY >+#define __P110 PAGE_COPY_X > #define __P111 PAGE_COPY_X > > #define __S000 PAGE_NONE >-#define __S001 PAGE_READONLY_X >-#define __S010 PAGE_SHARED >-#define __S011 PAGE_SHARED_X >-#define __S100 PAGE_READONLY >+#define __S001 PAGE_READONLY_NOEXEC >+#define __S010 PAGE_SHARED_NOEXEC >+#define __S011 PAGE_SHARED_NOEXEC >+#define __S100 PAGE_READONLY_X > #define __S101 PAGE_READONLY_X >-#define __S110 PAGE_SHARED >+#define __S110 PAGE_SHARED_X > #define __S111 PAGE_SHARED_X > > #ifndef __ASSEMBLY__ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc/a.out.h linux-2.4.22-ppc-dev/include/asm-sparc/a.out.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc/a.out.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc/a.out.h 2003-09-14 14:07:42.000000000 +0200 >@@ -91,7 +91,7 @@ > > #include <asm/page.h> > >-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE) >+#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE) > > #endif /* __KERNEL__ */ > >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc/elf.h linux-2.4.22-ppc-dev/include/asm-sparc/elf.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc/elf.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc/elf.h 2003-09-14 14:07:42.000000000 +0200 >@@ -83,6 +83,18 @@ > > #define ELF_ET_DYN_BASE (0x08000000) > >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL >+ >+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_MMAP_LEN(tsk) 16 >+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_EXEC_LEN(tsk) 16 >+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_STACK_LEN(tsk) 16 >+#endif >+ >+ > /* This yields a mask that user programs can use to figure out what > instruction set this cpu supports. This can NOT be done in userspace > on Sparc. */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc/mman.h linux-2.4.22-ppc-dev/include/asm-sparc/mman.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc/mman.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc/mman.h 2003-09-14 14:07:42.000000000 +0200 >@@ -24,6 +24,10 @@ > #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ > #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+#define MAP_MIRROR 0x0400 >+#endif >+ > #define MS_ASYNC 1 /* sync memory asynchronously */ > #define MS_INVALIDATE 2 /* invalidate the caches */ > #define MS_SYNC 4 /* synchronous memory sync */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc/pgtable.h linux-2.4.22-ppc-dev/include/asm-sparc/pgtable.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc/pgtable.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc/pgtable.h 2003-09-14 14:07:42.000000000 +0200 >@@ -97,6 +97,13 @@ > BTFIXUPDEF_INT(page_shared) > BTFIXUPDEF_INT(page_copy) > BTFIXUPDEF_INT(page_readonly) >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+BTFIXUPDEF_INT(page_shared_noexec) >+BTFIXUPDEF_INT(page_copy_noexec) >+BTFIXUPDEF_INT(page_readonly_noexec) >+#endif >+ > BTFIXUPDEF_INT(page_kernel) > > #define PMD_SHIFT BTFIXUP_SIMM13(pmd_shift) >@@ -118,6 +125,16 @@ > #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy)) > #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly)) > >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+#define PAGE_SHARED_NOEXEC __pgprot(BTFIXUP_INT(page_shared_noexec)) >+#define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec)) >+#define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec)) >+#else >+#define PAGE_SHARED_NOEXEC PAGE_SHARED >+#define PAGE_COPY_NOEXEC PAGE_COPY >+#define PAGE_READONLY_NOEXEC PAGE_READONLY >+#endif >+ > extern unsigned long page_kernel; > > #ifdef MODULE >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc/pgtsrmmu.h linux-2.4.22-ppc-dev/include/asm-sparc/pgtsrmmu.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc/pgtsrmmu.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc/pgtsrmmu.h 2003-09-14 14:07:42.000000000 +0200 >@@ -73,6 +73,15 @@ > SRMMU_EXEC | SRMMU_REF) > #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \ > SRMMU_EXEC | SRMMU_REF) >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ >+ SRMMU_WRITE | SRMMU_REF) >+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ >+ SRMMU_REF) >+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \ >+ SRMMU_REF) >+#endif >+ > #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \ > SRMMU_DIRTY | SRMMU_REF) > >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc/uaccess.h linux-2.4.22-ppc-dev/include/asm-sparc/uaccess.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc/uaccess.h 2003-09-14 14:03:15.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc/uaccess.h 2003-09-14 14:07:42.000000000 +0200 >@@ -39,7 +39,7 @@ > * No one can read/write anything from userland in the kernel space by setting > * large size and address near to PAGE_OFFSET - a fault will break his intentions. > */ >-#define __user_ok(addr,size) ((addr) < STACK_TOP) >+#define __user_ok(addr,size) ((addr) < __STACK_TOP) > #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) > #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) > #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc64/a.out.h linux-2.4.22-ppc-dev/include/asm-sparc64/a.out.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc64/a.out.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc64/a.out.h 2003-09-14 14:07:42.000000000 +0200 >@@ -95,7 +95,7 @@ > > #ifdef __KERNEL__ > >-#define STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L) >+#define __STACK_TOP (current->thread.flags & SPARC_FLAG_32BIT ? 0xf0000000 : 0x80000000000L) > > #endif > >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc64/elf.h linux-2.4.22-ppc-dev/include/asm-sparc64/elf.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc64/elf.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc64/elf.h 2003-09-14 14:07:42.000000000 +0200 >@@ -82,6 +82,17 @@ > #define ELF_ET_DYN_BASE 0x0000010000000000UL > #endif > >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 0x10000UL : 0x100000UL) >+ >+#define PAX_DELTA_MMAP_LSB(tsk) (PAGE_SHIFT + 1) >+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 ) >+#define PAX_DELTA_EXEC_LSB(tsk) (PAGE_SHIFT + 1) >+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 14 : 28 ) >+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT >+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->thread.flags & SPARC_FLAG_32BIT ? 15 : 29 ) >+#endif >+ > > /* This yields a mask that user programs can use to figure out what > instruction set this cpu supports. */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc64/mman.h linux-2.4.22-ppc-dev/include/asm-sparc64/mman.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc64/mman.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc64/mman.h 2003-09-14 14:07:42.000000000 +0200 >@@ -24,6 +24,10 @@ > #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ > #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+#define MAP_MIRROR 0x0400 >+#endif >+ > #define MS_ASYNC 1 /* sync memory asynchronously */ > #define MS_INVALIDATE 2 /* invalidate the caches */ > #define MS_SYNC 4 /* synchronous memory sync */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/asm-sparc64/pgtable.h linux-2.4.22-ppc-dev/include/asm-sparc64/pgtable.h >--- linux-2.4.22-ppc-dev.orig/include/asm-sparc64/pgtable.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/asm-sparc64/pgtable.h 2003-09-14 14:07:42.000000000 +0200 >@@ -122,7 +122,8 @@ > #define _PAGE_G 0x0000000000000001 /* Global */ > > /* Here are the SpitFire software bits we use in the TTE's. */ >-#define _PAGE_MODIFIED 0x0000000000000800 /* Modified Page (ie. dirty) */ >+#define _PAGE_MODIFIED 0x0000000000001000 /* Modified Page (ie. dirty) */ >+#define _PAGE_EXEC 0x0000000000000800 /* Executable SW bit */ > #define _PAGE_ACCESSED 0x0000000000000400 /* Accessed Page (ie. referenced) */ > #define _PAGE_READ 0x0000000000000200 /* Readable SW Bit */ > #define _PAGE_WRITE 0x0000000000000100 /* Writable SW Bit */ >@@ -150,16 +151,30 @@ > > /* Don't set the TTE _PAGE_W bit here, else the dirty bit never gets set. */ > #define PAGE_SHARED __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ >- __ACCESS_BITS | _PAGE_WRITE) >+ __ACCESS_BITS | _PAGE_WRITE | _PAGE_EXEC) > > #define PAGE_COPY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ >- __ACCESS_BITS) >+ __ACCESS_BITS | _PAGE_EXEC) > > #define PAGE_READONLY __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ >- __ACCESS_BITS) >+ __ACCESS_BITS | _PAGE_EXEC) > > #define PAGE_KERNEL __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ >- __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS) >+ __PRIV_BITS | __ACCESS_BITS | __DIRTY_BITS | \ >+ _PAGE_EXEC) >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+#define PAGE_SHARED_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ >+ __ACCESS_BITS | _PAGE_WRITE) >+#define PAGE_COPY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ >+ __ACCESS_BITS) >+#define PAGE_READONLY_NOEXEC __pgprot (_PAGE_PRESENT | _PAGE_VALID | _PAGE_CACHE | \ >+ __ACCESS_BITS) >+#else >+#define PAGE_SHARED_NOEXEC PAGE_SHARED >+#define PAGE_COPY_NOEXEC PAGE_COPY >+#define PAGE_READONLY_NOEXEC PAGE_READONLY >+#endif > > #define PAGE_INVALID __pgprot (0) > >@@ -170,18 +185,18 @@ > #define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E) > > #define __P000 PAGE_NONE >-#define __P001 PAGE_READONLY >-#define __P010 PAGE_COPY >-#define __P011 PAGE_COPY >+#define __P001 PAGE_READONLY_NOEXEC >+#define __P010 PAGE_COPY_NOEXEC >+#define __P011 PAGE_COPY_NOEXEC > #define __P100 PAGE_READONLY > #define __P101 PAGE_READONLY > #define __P110 PAGE_COPY > #define __P111 PAGE_COPY > > #define __S000 PAGE_NONE >-#define __S001 PAGE_READONLY >-#define __S010 PAGE_SHARED >-#define __S011 PAGE_SHARED >+#define __S001 PAGE_READONLY_NOEXEC >+#define __S010 PAGE_SHARED_NOEXEC >+#define __S011 PAGE_SHARED_NOEXEC > #define __S100 PAGE_READONLY > #define __S101 PAGE_READONLY > #define __S110 PAGE_SHARED >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/a.out.h linux-2.4.22-ppc-dev/include/linux/a.out.h >--- linux-2.4.22-ppc-dev.orig/include/linux/a.out.h 2003-09-14 14:03:11.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/a.out.h 2003-09-14 14:07:42.000000000 +0200 >@@ -7,6 +7,16 @@ > > #include <asm/a.out.h> > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDUSTACK >+#define __DELTA_STACK (current->mm->delta_stack) >+#else >+#define __DELTA_STACK 0UL >+#endif >+ >+#ifndef STACK_TOP >+#define STACK_TOP (__STACK_TOP - __DELTA_STACK) >+#endif >+ > #endif /* __STRUCT_EXEC_OVERRIDE__ */ > > /* these go in the N_MACHTYPE field */ >@@ -37,6 +47,14 @@ > M_MIPS2 = 152 /* MIPS R6000/R4000 binary */ > }; > >+/* Constants for the N_FLAGS field */ >+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ >+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */ >+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */ >+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */ >+#define F_PAX_RANDEXEC 16 /* Randomize ET_EXEC base */ >+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ >+ > #if !defined (N_MAGIC) > #define N_MAGIC(exec) ((exec).a_info & 0xffff) > #endif >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/binfmts.h linux-2.4.22-ppc-dev/include/linux/binfmts.h >--- linux-2.4.22-ppc-dev.orig/include/linux/binfmts.h 2003-09-14 14:03:11.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/binfmts.h 2003-09-14 14:07:42.000000000 +0200 >@@ -59,6 +59,8 @@ > extern int do_coredump(long signr, struct pt_regs * regs); > extern void set_binfmt(struct linux_binfmt *new); > >+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp); >+void pax_report_insns(void *pc); > > #if 0 > /* this went away now */ >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/elf.h linux-2.4.22-ppc-dev/include/linux/elf.h >--- linux-2.4.22-ppc-dev.orig/include/linux/elf.h 2003-09-14 14:03:11.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/elf.h 2003-09-14 14:07:42.000000000 +0200 >@@ -117,6 +117,8 @@ > #define DT_DEBUG 21 > #define DT_TEXTREL 22 > #define DT_JMPREL 23 >+#define DT_FLAGS 30 >+#define DF_TEXTREL 0x00000004 > #define DT_LOPROC 0x70000000 > #define DT_HIPROC 0x7fffffff > #define DT_MIPS_RLD_VERSION 0x70000001 >@@ -255,6 +257,13 @@ > #define R_MIPS_LOVENDOR 100 > #define R_MIPS_HIVENDOR 127 > >+/* Constants for the e_flags field */ >+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */ >+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */ >+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */ >+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */ >+#define EF_PAX_RANDEXEC 16 /* Randomize ET_EXEC base */ >+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */ > > /* > * Sparc ELF relocation types >@@ -550,6 +559,8 @@ > #define EI_VERSION 6 > #define EI_PAD 7 > >+#define EI_PAX 14 >+ > #define ELFMAG0 0x7f /* EI_MAG */ > #define ELFMAG1 'E' > #define ELFMAG2 'L' >@@ -597,6 +608,7 @@ > #define elfhdr elf32_hdr > #define elf_phdr elf32_phdr > #define elf_note elf32_note >+#define elf_dyn Elf32_Dyn > > #else > >@@ -604,6 +616,7 @@ > #define elfhdr elf64_hdr > #define elf_phdr elf64_phdr > #define elf_note elf64_note >+#define elf_dyn Elf64_Dyn > > #endif > >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/fs.h linux-2.4.22-ppc-dev/include/linux/fs.h >--- linux-2.4.22-ppc-dev.orig/include/linux/fs.h 2003-09-14 14:07:49.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/fs.h 2003-09-14 14:07:42.000000000 +0200 >@@ -1091,7 +1091,7 @@ > > asmlinkage long sys_open(const char *, int, int); > asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */ >-extern int do_truncate(struct dentry *, loff_t start); >+extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *); > > extern struct file *filp_open(const char *, int, int); > extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/gracl.h linux-2.4.22-ppc-dev/include/linux/gracl.h >--- linux-2.4.22-ppc-dev.orig/include/linux/gracl.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/linux/gracl.h 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,212 @@ >+#ifndef GR_ACL_H >+#define GR_ACL_H >+#endif >+#include <linux/grdefs.h> >+#include <linux/resource.h> >+ >+#include <asm/resource.h> >+ >+/* * * * * * * * * * * * * * * * * * * * * >+ * grsecurity ACL System >+ * Main header file >+ * Purpose: define most gracl data structures >+ * * * * * * * * * * * * * * * * * * * * */ >+ >+/* Major status information */ >+ >+#define GR_VERSION "grsecurity 2.0" >+ >+enum { >+ >+ SHUTDOWN = 0, >+ ENABLE = 1, >+ SPROLE = 2, >+ RELOAD = 3, >+ SEGVMOD = 4, >+ STATUS = 5, >+ UNSPROLE = 6 >+}; >+ >+/* Password setup definitions >+ * kernel/grhash.c */ >+enum { >+ GR_PW_LEN = 128, >+ GR_SALT_LEN = 16, >+ GR_SHA_LEN = 32, >+}; >+ >+enum { >+ GR_SPROLE_LEN = 64, >+}; >+ >+/* Begin Data Structures */ >+ >+struct sprole_pw { >+ unsigned char *rolename; >+ unsigned char salt[GR_SALT_LEN]; >+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */ >+}; >+ >+struct name_entry { >+ ino_t inode; >+ kdev_t device; >+ char *name; >+ __u16 len; >+}; >+ >+struct acl_role_db { >+ struct acl_role_label **r_hash; >+ __u32 r_size; >+}; >+ >+struct name_db { >+ struct name_entry **n_hash; >+ __u32 n_size; >+}; >+ >+struct crash_uid { >+ uid_t uid; >+ unsigned long expires; >+}; >+ >+/* Userspace Grsecurity ACL data structures */ >+struct acl_subject_label { >+ char *filename; >+ ino_t inode; >+ kdev_t device; >+ __u32 mode; >+ __u32 cap_raise; >+ __u32 cap_lower; >+ >+ struct rlimit res[RLIM_NLIMITS + 1]; >+ __u16 resmask; >+ >+ __u32 ip_proto[8]; >+ __u32 ip_type; >+ struct acl_ip_label **ips; >+ __u32 ip_num; >+ >+ __u32 crashes; >+ unsigned long expires; >+ >+ struct acl_subject_label *parent_subject; >+ struct acl_object_label *proc_object; >+ struct acl_ip_label *ip_object; >+ struct acl_subject_label *prev; >+ struct acl_subject_label *next; >+ >+ struct acl_object_label **obj_hash; >+ __u32 obj_hash_size; >+}; >+ >+struct role_allowed_ip { >+ __u32 addr; >+ __u32 netmask; >+ >+ struct role_allowed_ip *prev; >+ struct role_allowed_ip *next; >+}; >+ >+struct role_transition { >+ char *rolename; >+ >+ struct role_transition *prev; >+ struct role_transition *next; >+}; >+ >+struct acl_role_label { >+ char *rolename; >+ uid_t uidgid; >+ __u16 roletype; >+ >+ __u16 auth_attempts; >+ unsigned long expires; >+ >+ struct acl_subject_label *root_label; >+ struct acl_subject_label *proc_subject; >+ >+ struct acl_role_label *prev; >+ struct acl_role_label *next; >+ >+ struct role_transition *transitions; >+ struct role_allowed_ip *allowed_ips; >+ struct acl_subject_label **subj_hash; >+ __u32 subj_hash_size; >+}; >+ >+struct user_acl_role_db { >+ struct acl_role_label **r_table; >+ __u32 r_entries; /* number of entries in table */ >+ __u32 s_entries; /* total number of subject acls */ >+ __u32 i_entries; /* total number of ip acls */ >+ __u32 o_entries; /* Total number of object acls */ >+ __u32 a_entries; /* total number of allowed ips */ >+ __u32 t_entries; /* total number of transitions */ >+}; >+ >+struct acl_object_label { >+ char *filename; >+ ino_t inode; >+ kdev_t device; >+ __u32 mode; >+ >+ struct acl_subject_label *nested; >+ >+ /* next two structures not used */ >+ >+ struct acl_object_label *prev; >+ struct acl_object_label *next; >+}; >+ >+struct acl_ip_label { >+ __u32 addr; >+ __u32 netmask; >+ __u16 low, high; >+ __u8 mode; >+ __u32 type; >+ __u32 proto[8]; >+ >+ /* next two structures not used */ >+ >+ struct acl_ip_label *prev; >+ struct acl_ip_label *next; >+}; >+ >+struct gr_arg { >+ struct user_acl_role_db role_db; >+ unsigned char pw[GR_PW_LEN]; >+ unsigned char salt[GR_SALT_LEN]; >+ unsigned char sum[GR_SHA_LEN]; >+ unsigned char sp_role[GR_SPROLE_LEN]; >+ struct sprole_pw *sprole_pws; >+ __u16 num_sprole_pws; >+ kdev_t segv_device; >+ ino_t segv_inode; >+ uid_t segv_uid; >+ __u16 mode; >+}; >+ >+/* End Data Structures Section */ >+ >+/* Hash functions generated by empirical testing by Brad Spengler >+ Makes good use of the low bits of the inode. Generally 0-1 times >+ in loop for successful match. 0-3 for unsuccessful match. >+ Shift/add algorithm with modulus of table size and an XOR*/ >+ >+static __inline__ unsigned long >+rhash(const uid_t uid, const __u16 type, const unsigned long sz) >+{ >+ return (((uid << type) + (uid ^ type)) % sz); >+} >+ >+static __inline__ unsigned long >+fhash(const ino_t ino, const kdev_t dev, const unsigned long sz) >+{ >+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz); >+} >+ >+static __inline__ unsigned long >+nhash(const char *name, const __u16 len, const unsigned long sz) >+{ >+ return full_name_hash(name, len) % sz; >+} >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/gralloc.h linux-2.4.22-ppc-dev/include/linux/gralloc.h >--- linux-2.4.22-ppc-dev.orig/include/linux/gralloc.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/linux/gralloc.h 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,8 @@ >+#ifndef __GRALLOC_H >+#define __GRALLOC_H >+ >+void acl_free_all(void); >+int acl_alloc_stack_init(unsigned long size); >+void *acl_alloc(unsigned long len); >+ >+#endif >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/grdefs.h linux-2.4.22-ppc-dev/include/linux/grdefs.h >--- linux-2.4.22-ppc-dev.orig/include/linux/grdefs.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/linux/grdefs.h 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,104 @@ >+#ifndef GRDEFS_H >+#define GRDEFS_H >+ >+/* Begin grsecurity status declarations */ >+ >+enum { >+ GR_READY = 0x01, >+ GR_STATUS_INIT = 0x00 // disabled state >+}; >+ >+/* Begin ACL declarations */ >+ >+/* Role flags */ >+ >+enum { >+ GR_ROLE_USER = 0x0001, >+ GR_ROLE_GROUP = 0x0002, >+ GR_ROLE_DEFAULT = 0x0004, >+ GR_ROLE_SPECIAL = 0x0008, >+ GR_ROLE_AUTH = 0x0010, >+ GR_ROLE_NOPW = 0x0020, >+ GR_ROLE_GOD = 0x0040, >+ GR_ROLE_LEARN = 0x0080, >+ GR_ROLE_TPE = 0x0100 >+}; >+ >+/* ACL Subject and Object mode flags */ >+enum { >+ GR_DELETED = 0x00000080 >+}; >+ >+/* ACL Object-only mode flags */ >+enum { >+ GR_READ = 0x00000001, >+ GR_APPEND = 0x00000002, >+ GR_WRITE = 0x00000004, >+ GR_EXEC = 0x00000008, >+ GR_FIND = 0x00000010, >+ GR_INHERIT = 0x00000040, >+ GR_PTRACERD = 0x00000100, >+ GR_SETID = 0x00000200, >+ GR_CREATE = 0x00000400, >+ GR_DELETE = 0x00000800, >+ GR_AUDIT_READ = 0x00001000, >+ GR_AUDIT_APPEND = 0x00002000, >+ GR_AUDIT_WRITE = 0x0004000, >+ GR_AUDIT_EXEC = 0x00008000, >+ GR_AUDIT_FIND = 0x00010000, >+ GR_AUDIT_INHERIT = 0x00020000, >+ GR_AUDIT_SETID = 0x00400000, >+ GR_AUDIT_CREATE = 0x00800000, >+ GR_AUDIT_DELETE = 0x01000000, >+ GR_SUPPRESS = 0x02000000, >+ GR_NOLEARN = 0x04000000 >+}; >+ >+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \ >+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \ >+ GR_AUDIT_CREATE | GR_AUDIT_DELETE) >+ >+/* ACL subject-only mode flags */ >+enum { >+ GR_KILL = 0x00000001, >+ GR_VIEW = 0x00000002, >+ GR_PROTECTED = 0x00000100, >+ GR_LEARN = 0x00000200, >+ GR_OVERRIDE = 0x00000400, >+ /* just a placeholder, this mode is only used in userspace */ >+ GR_DUMMY = 0x00000800, >+ >+ GR_PAXPAGE = 0x00001000, >+ GR_PAXSEGM = 0x00002000, >+ GR_PAXGCC = 0x00004000, >+ GR_PAXRANDMMAP = 0x00008000, >+ GR_PAXRANDEXEC = 0x00010000, >+ GR_PAXMPROTECT = 0x00020000, >+ GR_PROTSHM = 0x00040000, >+ GR_KILLPROC = 0x00080000, >+ GR_KILLIPPROC = 0x00100000, >+ /* just a placeholder, this mode is only used in userspace */ >+ GR_NOTROJAN = 0x00200000, >+ GR_PROTPROCFD = 0x00400000, >+ GR_PROCACCT = 0x00800000 >+}; >+ >+#define GR_CRASH_RES 11 >+#define GR_UIDTABLE_MAX 500 >+ >+/* begin resource learning section */ >+enum { >+ GR_RLIM_CPU_BUMP = 60, >+ GR_RLIM_FSIZE_BUMP = 50000, >+ GR_RLIM_DATA_BUMP = 10000, >+ GR_RLIM_STACK_BUMP = 1000, >+ GR_RLIM_CORE_BUMP = 10000, >+ GR_RLIM_RSS_BUMP = 500000, >+ GR_RLIM_NPROC_BUMP = 1, >+ GR_RLIM_NOFILE_BUMP = 5, >+ GR_RLIM_MEMLOCK_BUMP = 50000, >+ GR_RLIM_AS_BUMP = 500000, >+ GR_RLIM_LOCKS_BUMP = 2 >+}; >+ >+#endif >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/grinternal.h linux-2.4.22-ppc-dev/include/linux/grinternal.h >--- linux-2.4.22-ppc-dev.orig/include/linux/grinternal.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/linux/grinternal.h 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,193 @@ >+#ifndef __GRINTERNAL_H >+#define __GRINTERNAL_H >+ >+#ifdef CONFIG_GRKERNSEC >+ >+#include <linux/grdefs.h> >+#include <linux/grmsg.h> >+ >+extern void gr_add_learn_entry(const char *fmt, ...); >+extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode, >+ const struct vfsmount *mnt); >+extern __u32 gr_check_create(const struct dentry *new_dentry, >+ const struct dentry *parent, >+ const struct vfsmount *mnt, const __u32 mode); >+extern int gr_check_protected_task(const struct task_struct *task); >+extern __inline__ __u32 to_gr_audit(const __u32 reqmode); >+extern int gr_handle_rename(struct inode *old_dir, struct inode *new_dir, >+ struct dentry *old_dentry, >+ struct dentry *new_dentry, >+ struct vfsmount *mnt, const __u8 replace); >+extern int gr_set_acls(const int type); >+ >+extern void gr_handle_alertkill(void); >+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_link; >+extern int grsec_enable_fifo; >+extern int grsec_enable_execve; >+extern int grsec_enable_forkbomb; >+extern int grsec_forkbomb_gid; >+extern int grsec_forkbomb_sec; >+extern int grsec_forkbomb_max; >+extern int grsec_enable_execlog; >+extern int grsec_enable_signal; >+extern int grsec_enable_forkfail; >+extern int grsec_enable_time; >+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_sidcaps; >+extern int grsec_enable_randpid; >+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_audit_gid; >+extern int grsec_enable_group; >+extern int grsec_enable_audit_ipc; >+extern int grsec_enable_mount; >+extern int grsec_enable_chdir; >+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 security_alert_good(normal_msg,args...) \ >+({ \ >+ spin_lock(&grsec_alertgood_lock); \ >+ \ >+ if (!grsec_alertgood_wtime || jiffies - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \ >+ grsec_alertgood_wtime = jiffies; grsec_alertgood_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_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \ >+ grsec_alertgood_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_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \ >+ grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet++; \ >+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \ >+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \ >+ } \ >+ \ >+ spin_unlock(&grsec_alertgood_lock); \ >+}) >+ >+#define 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); \ >+ } \ >+ \ >+ gr_handle_alertkill(); \ >+ 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); \ >+}) >+ >+#define security_learn(normal_msg,args...) \ >+({ \ >+ gr_add_learn_entry(normal_msg "\n", ## args); \ >+}) >+ >+#endif >+ >+#endif >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/grmsg.h linux-2.4.22-ppc-dev/include/linux/grmsg.h >--- linux-2.4.22-ppc-dev.orig/include/linux/grmsg.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/linux/grmsg.h 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,104 @@ >+#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_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%d/%d gid/egid:%d/%d run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%d/%d gid/egid:%d/%d" >+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG >+#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG >+#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG >+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG >+#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_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG >+#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG >+#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG >+#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG >+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG >+#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%u.%u.%u.%u" >+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG >+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG >+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG >+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG >+#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG >+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG >+#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG >+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG >+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG >+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG >+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG >+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG >+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG >+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG >+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG >+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG >+#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG >+#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG >+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG >+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds" >+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution of [%.16s:%lu] for %lu seconds" >+#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_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG >+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG >+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG >+#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG >+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG >+#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG >+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG >+#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG >+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG >+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG >+#define GR_INITF_ACL_MSG "init_variables() failed %s" >+#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader" >+#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required" >+#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG >+#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG >+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG >+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG >+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG >+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG >+#define GR_ENABLE_ACL_MSG "Loaded %s" >+#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled." >+#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system" >+#define GR_RELOAD_ACL_MSG "Reloaded %s" >+#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG >+#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG >+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG >+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG >+#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG >+#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG >+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG >+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG >+#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG >+#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication" >+#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " 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_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG >+#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG >+#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG >+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG >+#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG >+#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG >+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG >+#define GR_TIME_MSG "time set by " DEFAULTSECMSG >+#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)" >+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG >+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG >+#define GR_SOCK_MSG "attempted socket(%.16s,%.16s,%.16s) by " DEFAULTSECMSG >+#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG >+#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG >+#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG >+#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG >+#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%u.%u.%u.%u\t%u\t%u\t%u\t%u\t%u.%u.%u.%u" >+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG >+#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG >+#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG >+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG >+#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG >+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG >+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG >+#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG >+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG >+#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG >+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG >+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG >+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG >+#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/grsecurity.h linux-2.4.22-ppc-dev/include/linux/grsecurity.h >--- linux-2.4.22-ppc-dev.orig/include/linux/grsecurity.h 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/include/linux/grsecurity.h 2003-09-14 14:07:42.000000000 +0200 >@@ -0,0 +1,174 @@ >+#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 int gr_handle_rawio(const struct inode *inode); >+extern int gr_handle_nproc(void); >+ >+extern void gr_handle_ioperm(void); >+extern void gr_handle_iopl(void); >+ >+extern int gr_tpe_allow(const struct file *file); >+ >+extern int gr_random_pid(spinlock_t * pid_lock); >+ >+extern void gr_log_forkfail(const int retval); >+extern void gr_log_timechange(void); >+extern void gr_log_signal(const int sig, const struct task_struct *t); >+extern void gr_log_chdir(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern void gr_log_chroot_exec(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv); >+extern void gr_log_remount(const char *devname, const int retval); >+extern void gr_log_unmount(const char *devname, const int retval); >+extern void gr_log_mount(const char *from, const char *to, const int retval); >+extern void gr_log_msgget(const int ret, const int msgflg); >+extern void gr_log_msgrm(const uid_t uid, const uid_t cuid); >+extern void gr_log_semget(const int err, const int semflg); >+extern void gr_log_semrm(const uid_t uid, const uid_t cuid); >+extern void gr_log_shmget(const int err, const int shmflg, const size_t size); >+extern void gr_log_shmrm(const uid_t uid, const uid_t cuid); >+ >+extern int gr_handle_follow_link(const struct inode *parent, >+ const struct inode *inode, >+ const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern int gr_handle_fifo(const struct dentry *dentry, >+ const struct vfsmount *mnt, >+ const struct dentry *dir, const int flag, >+ const int acc_mode); >+extern int gr_handle_hardlink(const struct dentry *dentry, >+ const struct vfsmount *mnt, >+ struct inode *inode, >+ const int mode, const char *to); >+ >+extern int gr_is_capable(const int cap); >+extern void gr_learn_resource(const struct task_struct *task, const int limit, >+ const unsigned long wanted); >+extern void gr_copy_label(struct task_struct *tsk); >+extern void gr_handle_crash(struct task_struct *task, const int sig); >+extern int gr_handle_signal(const struct task_struct *p, const int sig); >+extern int gr_check_crash_uid(const uid_t uid); >+extern int gr_check_protected_task(const struct task_struct *task); >+extern int gr_acl_handle_mmap(const struct file *file, >+ const unsigned long prot); >+extern int gr_acl_handle_mprotect(const struct file *file, >+ const unsigned long prot); >+extern int gr_check_hidden_task(const struct task_struct *tsk); >+extern __u32 gr_acl_handle_truncate(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern __u32 gr_acl_handle_utime(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern __u32 gr_acl_handle_access(const struct dentry *dentry, >+ const struct vfsmount *mnt, const int fmode); >+extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry, >+ const struct vfsmount *mnt, mode_t mode); >+extern __u32 gr_acl_handle_chmod(const struct dentry *dentry, >+ const struct vfsmount *mnt, mode_t mode); >+extern __u32 gr_acl_handle_chown(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern int gr_handle_ptrace_exec(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern int gr_handle_ptrace(struct task_struct *task, const long request); >+extern int gr_handle_mmap(const struct file *filp, const unsigned long prot); >+extern __u32 gr_acl_handle_execve(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern int gr_check_crash_exec(const struct file *filp); >+extern int gr_acl_is_enabled(void); >+extern void gr_set_kernel_label(struct task_struct *task); >+extern void gr_set_role_label(struct task_struct *task, const uid_t uid, >+ const gid_t gid); >+extern void gr_set_proc_label(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern __u32 gr_acl_handle_open(const struct dentry *dentry, >+ const struct vfsmount *mnt, const int fmode); >+extern __u32 gr_acl_handle_creat(const struct dentry *dentry, >+ const struct dentry *p_dentry, >+ const struct vfsmount *p_mnt, const int fmode, >+ const int imode); >+extern void gr_handle_create(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry, >+ const struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt, >+ const int mode); >+extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry, >+ const struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt); >+extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern void gr_handle_delete(const ino_t ino, const kdev_t dev); >+extern __u32 gr_acl_handle_unlink(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry, >+ const struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt, >+ const char *from); >+extern __u32 gr_acl_handle_link(const struct dentry *new_dentry, >+ const struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt, >+ const struct dentry *old_dentry, >+ const struct vfsmount *old_mnt, const char *to); >+extern int gr_acl_handle_rename(struct dentry *new_dentry, >+ struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt, >+ struct dentry *old_dentry, >+ struct inode *old_parent_inode, >+ struct vfsmount *old_mnt, const char *newname); >+extern __u32 gr_check_link(const struct dentry *new_dentry, >+ const struct dentry *parent_dentry, >+ const struct vfsmount *parent_mnt, >+ const struct dentry *old_dentry, >+ const struct vfsmount *old_mnt); >+extern __u32 gr_acl_handle_filldir(const struct dentry *dentry, >+ const struct vfsmount *mnt, const ino_t ino); >+extern __u32 gr_acl_handle_unix(const struct dentry *dentry, >+ const struct vfsmount *mnt); >+extern void gr_set_pax_flags(struct task_struct *task); >+extern void gr_acl_handle_exit(void); >+extern void gr_acl_handle_psacct(struct task_struct *task, const long code); >+extern int gr_acl_handle_procpidmem(const struct task_struct *task); >+extern __u32 gr_cap_rtnetlink(void); >+ >+#ifdef CONFIG_GRKERNSEC >+extern void gr_handle_mem_write(void); >+extern void gr_handle_kmem_write(void); >+extern void gr_handle_open_port(void); >+extern int gr_handle_mem_mmap(const unsigned long offset, >+ struct vm_area_struct *vma); >+ >+extern __u16 ip_randomid(void); >+extern __u32 ip_randomisn(void); >+extern unsigned long get_random_long(void); >+ >+extern int grsec_enable_dmesg; >+extern int grsec_enable_randid; >+extern int grsec_enable_randisn; >+extern int grsec_enable_randsrc; >+extern int grsec_enable_randrpc; >+#endif >+ >+#endif >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/kernel.h linux-2.4.22-ppc-dev/include/linux/kernel.h >--- linux-2.4.22-ppc-dev.orig/include/linux/kernel.h 2003-09-14 14:03:11.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/kernel.h 2003-09-14 14:07:42.000000000 +0200 >@@ -71,14 +71,17 @@ > extern long long simple_strtoll(const char *,char **,unsigned int); > extern int sprintf(char * buf, const char * fmt, ...) > __attribute__ ((format (printf, 2, 3))); >-extern int vsprintf(char *buf, const char *, va_list); >+extern int vsprintf(char *buf, const char *, va_list) >+ __attribute__ ((format (printf, 2, 0))); > extern int snprintf(char * buf, size_t size, const char * fmt, ...) > __attribute__ ((format (printf, 3, 4))); >-extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); >+extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) >+ __attribute__ ((format (printf, 3, 0))); > > extern int sscanf(const char *, const char *, ...) > __attribute__ ((format (scanf,2,3))); >-extern int vsscanf(const char *, const char *, va_list); >+extern int vsscanf(const char *, const char *, va_list) >+ __attribute__ ((format (scanf, 2, 0))); > > extern int get_option(char **str, int *pint); > extern char *get_options(char *str, int nints, int *ints); >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/mm.h linux-2.4.22-ppc-dev/include/linux/mm.h >--- linux-2.4.22-ppc-dev.orig/include/linux/mm.h 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/mm.h 2003-09-14 14:07:42.000000000 +0200 >@@ -22,9 +22,13 @@ > extern struct list_head active_list; > extern struct list_head inactive_list; > >+extern void gr_learn_resource(const struct task_struct * task, const int limit, >+ const unsigned long wanted); >+ > #include <asm/page.h> > #include <asm/pgtable.h> > #include <asm/atomic.h> >+#include <asm/mman.h> > > /* > * Linux kernel virtual memory manager primitives. >@@ -104,6 +108,33 @@ > #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */ > #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */ > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+#define VM_MIRROR 0x00100000 /* vma is mirroring another */ >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+#define VM_MAYNOTWRITE 0x00200000 /* vma cannot be granted VM_WRITE any more */ >+#endif >+ >+#ifdef ARCH_STACK_GROWSUP >+#define __VM_STACK_FLAGS 0x00000233 >+#else >+#define __VM_STACK_FLAGS 0x00000133 >+#endif >+ >+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+#define VM_STACK_FLAGS (__VM_STACK_FLAGS | \ >+ ((current->flags & PF_PAX_MPROTECT)?0:VM_MAYEXEC) | \ >+ ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC)) >+#else >+#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_MAYEXEC | \ >+ ((current->flags & (PF_PAX_PAGEEXEC|PF_PAX_SEGMEXEC))?0:VM_EXEC)) >+#endif >+#else >+#define VM_STACK_FLAGS (__VM_STACK_FLAGS | VM_EXEC | VM_MAYEXEC) >+#endif >+ > #ifndef VM_STACK_FLAGS > #define VM_STACK_FLAGS 0x00000177 > #endif >@@ -554,21 +585,49 @@ > unsigned long len, unsigned long prot, > unsigned long flag, unsigned long pgoff); > >+extern int do_munmap(struct mm_struct *, unsigned long, size_t); >+ > static inline unsigned long do_mmap(struct file *file, unsigned long addr, > unsigned long len, unsigned long prot, > unsigned long flag, unsigned long offset) > { > unsigned long ret = -EINVAL; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((current->flags & PF_PAX_SEGMEXEC) && >+ (len > SEGMEXEC_TASK_SIZE || (addr && addr > SEGMEXEC_TASK_SIZE-len))) >+ goto out; >+#endif >+ > if ((offset + PAGE_ALIGN(len)) < offset) > goto out; > if (!(offset & ~PAGE_MASK)) > ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) >+ if ((current->flags & PF_PAX_SEGMEXEC) && !BAD_ADDR(ret) && >+ (prot & PROT_EXEC) && ((flag & MAP_TYPE) == MAP_PRIVATE) >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+ && (!(current->flags & PF_PAX_MPROTECT) || (file && !(prot & PROT_WRITE))) >+#endif >+ ) >+ { >+ unsigned long ret_m; >+ ret_m = do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flag | MAP_MIRROR | MAP_FIXED, ret); >+ if (BAD_ADDR(ret_m)) { >+ do_munmap(current->mm, ret, len); >+ ret = ret_m; >+ } >+ } >+#undef BAD_ADDR >+#endif >+ > out: > return ret; > } > >-extern int do_munmap(struct mm_struct *, unsigned long, size_t); >- > extern unsigned long do_brk(unsigned long, unsigned long); > > static inline void __vma_unlink(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct * prev) >@@ -581,6 +640,12 @@ > > static inline int can_vma_merge(struct vm_area_struct * vma, unsigned long vm_flags) > { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((vma->vm_flags | vm_flags) & VM_MIRROR) >+ return 0; >+#endif >+ > if (!vma->vm_file && vma->vm_flags == vm_flags) > return 1; > else >@@ -635,6 +700,12 @@ > return gfp_mask; > } > >+/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ >+extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr); >+extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr, >+ struct vm_area_struct **pprev); >+ >+ > extern int heap_stack_gap; > > /* >@@ -665,9 +736,50 @@ > goto out; > spin_lock(&vma->vm_mm->page_table_lock); > grow = (vma->vm_start - address) >> PAGE_SHIFT; >+ >+ gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address); >+ gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT); >+ gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT); >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (vma->vm_flags & VM_MIRROR) { >+ struct vm_area_struct * vma_m; >+ unsigned long address_m; >+ >+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data; >+ vma_m = find_vma(vma->vm_mm, address_m); >+ if (!vma_m || vma_m->vm_start != address_m || !(vma_m->vm_flags & VM_MIRROR) || >+ vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start) { >+ spin_unlock(&vma->vm_mm->page_table_lock); >+ printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n", >+ address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end); >+ return -ENOMEM; >+ } >+ >+ address_m = address + (unsigned long)vma->vm_private_data; >+ if (vma_m->vm_end - address_m > current->rlim[RLIMIT_STACK].rlim_cur || >+ ((vma_m->vm_mm->total_vm + 2*grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur || >+ ((vma_m->vm_flags & VM_LOCKED) && ((vma_m->vm_mm->locked_vm + 2*grow) << PAGE_SHIFT) > >+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) { >+ spin_unlock(&vma->vm_mm->page_table_lock); >+ return -ENOMEM; >+ } >+ >+ vma_m->vm_start = address_m; >+ vma_m->vm_pgoff -= grow; >+ vma_m->vm_mm->total_vm += grow; >+ if (vma_m->vm_flags & VM_LOCKED) >+ vma_m->vm_mm->locked_vm += grow; >+ } else >+#endif >+ > if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur || >- ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) >+ ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur || >+ ((vma->vm_flags & VM_LOCKED) && ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) > >+ current->rlim[RLIMIT_MEMLOCK].rlim_cur)) { > goto out_unlock; >+ } >+ > vma->vm_start = address; > vma->vm_pgoff -= grow; > vma->vm_mm->total_vm += grow; >@@ -680,11 +792,6 @@ > return err; > } > >-/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */ >-extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr); >-extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr, >- struct vm_area_struct **pprev); >- > /* Look up the first VMA which intersects the interval start_addr..end_addr-1, > NULL if none. Assume start_addr < end_addr. */ > static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr) >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/proc_fs.h linux-2.4.22-ppc-dev/include/linux/proc_fs.h >--- linux-2.4.22-ppc-dev.orig/include/linux/proc_fs.h 2003-09-14 14:03:11.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/proc_fs.h 2003-09-14 14:07:42.000000000 +0200 >@@ -143,6 +143,9 @@ > extern struct proc_dir_entry *proc_mknod(const char *,mode_t, > struct proc_dir_entry *,kdev_t); > extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *); >+#ifdef CONFIG_GRKERNSEC_PROC >+extern struct proc_dir_entry *proc_priv_mkdir(const char *, struct proc_dir_entry *); >+#endif > > static inline struct proc_dir_entry *create_proc_read_entry(const char *name, > mode_t mode, struct proc_dir_entry *base, >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/sched.h linux-2.4.22-ppc-dev/include/linux/sched.h >--- linux-2.4.22-ppc-dev.orig/include/linux/sched.h 2003-09-14 14:03:11.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/sched.h 2003-09-14 14:07:42.000000000 +0200 >@@ -27,6 +27,9 @@ > #include <linux/securebits.h> > #include <linux/fs_struct.h> > >+extern int gr_is_capable(const int cap); >+extern int gr_pid_is_chrooted(const struct task_struct *p); >+ > struct exec_domain; > > /* >@@ -227,6 +230,20 @@ > unsigned long cpu_vm_mask; > unsigned long swap_address; > >+#ifdef CONFIG_GRKERNSEC_PAX_DLRESOLVE >+ unsigned long call_dl_resolve; >+#endif >+ >+#if defined(CONFIG_PPC32) && defined(CONFIG_GRKERNSEC_PAX_EMUSIGRT) >+ unsigned long call_syscall; >+#endif >+ >+#ifdef CONFIG_GRKERNSEC_PAX_ASLR >+ unsigned long delta_mmap; /* PaX: randomized offset */ >+ unsigned long delta_exec; /* PaX: randomized offset */ >+ unsigned long delta_stack; /* PaX: randomized offset */ >+#endif >+ > unsigned dumpable:1; > > /* Architecture-specific MM context */ >@@ -406,7 +423,7 @@ > int (*notifier)(void *priv); > void *notifier_data; > sigset_t *notifier_mask; >- >+ > /* Thread group tracking */ > u32 parent_exec_id; > u32 self_exec_id; >@@ -415,6 +432,19 @@ > > /* journalling filesystem info */ > void *journal_info; >+ >+#ifdef CONFIG_GRKERNSEC >+/* added by grsecurity's ACL system */ >+ struct acl_subject_label *acl; >+ struct acl_role_label *role; >+ struct file *exec_file; >+ u32 curr_ip; >+ u16 acl_role_id; >+ u8 acl_sp_role:1; >+ u8 used_accept:1; >+ u8 used_connect:1; >+ u8 is_writable:1; >+#endif > }; > > /* >@@ -435,6 +465,13 @@ > > #define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ > >+#define PF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */ >+#define PF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */ >+#define PF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */ >+#define PF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */ >+#define PF_PAX_RANDEXEC 0x10000000 /* Randomize ET_EXEC base */ >+#define PF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */ >+ > /* > * Ptrace flags > */ >@@ -549,6 +586,8 @@ > *p->pidhash_pprev = p->pidhash_next; > } > >+#include <asm/current.h> >+ > static inline struct task_struct *find_task_by_pid(int pid) > { > struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)]; >@@ -556,6 +595,8 @@ > for(p = *htable; p && p->pid != pid; p = p->pidhash_next) > ; > >+ if(gr_pid_is_chrooted(p)) p = NULL; >+ > return p; > } > >@@ -576,8 +617,6 @@ > extern struct user_struct * alloc_uid(uid_t); > extern void free_uid(struct user_struct *); > >-#include <asm/current.h> >- > extern unsigned long volatile jiffies; > extern unsigned long itimer_ticks; > extern unsigned long itimer_next; >@@ -741,7 +780,7 @@ > static inline int capable(int cap) > { > #if 1 /* ok now */ >- if (cap_raised(current->cap_effective, cap)) >+ if (cap_raised(current->cap_effective, cap) && gr_is_capable(cap)) > #else > if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0) > #endif >diff -Naur linux-2.4.22-ppc-dev.orig/include/linux/sysctl.h linux-2.4.22-ppc-dev/include/linux/sysctl.h >--- linux-2.4.22-ppc-dev.orig/include/linux/sysctl.h 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/linux/sysctl.h 2003-09-14 14:07:42.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 -Naur linux-2.4.22-ppc-dev.orig/include/net/inetpeer.h linux-2.4.22-ppc-dev/include/net/inetpeer.h >--- linux-2.4.22-ppc-dev.orig/include/net/inetpeer.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/net/inetpeer.h 2003-09-14 14:07:42.000000000 +0200 >@@ -13,6 +13,7 @@ > #include <linux/init.h> > #include <linux/sched.h> > #include <linux/spinlock.h> >+ > #include <asm/atomic.h> > > struct inet_peer >@@ -34,6 +35,11 @@ > /* can be called with or without local BH being disabled */ > struct inet_peer *inet_getpeer(__u32 daddr, int create); > >+#ifdef CONFIG_GRKERNSEC_RANDID >+extern int grsec_enable_randid; >+extern __u16 ip_randomid(void); >+#endif >+ > extern spinlock_t inet_peer_unused_lock; > extern struct inet_peer *inet_peer_unused_head; > extern struct inet_peer **inet_peer_unused_tailp; >@@ -58,7 +64,14 @@ > __u16 id; > > spin_lock_bh(&inet_peer_idlock); >- id = p->ip_id_count++; >+ >+#ifdef CONFIG_GRKERNSEC_RANDID >+ if(grsec_enable_randid) >+ id = htons(ip_randomid()); >+ else >+#endif >+ id = p->ip_id_count++; >+ > spin_unlock_bh(&inet_peer_idlock); > return id; > } >diff -Naur linux-2.4.22-ppc-dev.orig/include/net/ip.h linux-2.4.22-ppc-dev/include/net/ip.h >--- linux-2.4.22-ppc-dev.orig/include/net/ip.h 2003-09-14 14:03:16.000000000 +0200 >+++ linux-2.4.22-ppc-dev/include/net/ip.h 2003-09-14 14:07:42.000000000 +0200 >@@ -64,6 +64,11 @@ > void (*destructor)(struct sock *); > }; > >+#ifdef CONFIG_GRKERNSEC_RANDID >+extern int grsec_enable_randid; >+extern __u16 ip_randomid(void); >+#endif >+ > extern struct ip_ra_chain *ip_ra_chain; > extern rwlock_t ip_ra_lock; > >@@ -197,7 +202,13 @@ > * does not change, they drop every other packet in > * a TCP stream using header compression. > */ >- iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0); >+ >+#ifdef CONFIG_GRKERNSEC_RANDID >+ if(grsec_enable_randid) >+ iph->id = htons(ip_randomid()); >+ else >+#endif >+ iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0); > } else > __ip_select_ident(iph, dst); > } >diff -Naur linux-2.4.22-ppc-dev.orig/init/main.c linux-2.4.22-ppc-dev/init/main.c >--- linux-2.4.22-ppc-dev.orig/init/main.c 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/init/main.c 2003-09-14 14:07:42.000000000 +0200 >@@ -27,6 +27,7 @@ > #include <linux/iobuf.h> > #include <linux/bootmem.h> > #include <linux/tty.h> >+#include <linux/grsecurity.h> > > #include <asm/io.h> > #include <asm/bugs.h> >@@ -111,6 +112,8 @@ > extern void ipc_init(void); > #endif > >+extern void grsecurity_init(void); >+ > /* > * Boot command-line arguments > */ >@@ -552,6 +555,7 @@ > do_basic_setup(); > > prepare_namespace(); >+ grsecurity_init(); > > /* > * Ok, we have completed the initial bootup, and >diff -Naur linux-2.4.22-ppc-dev.orig/ipc/msg.c linux-2.4.22-ppc-dev/ipc/msg.c >--- linux-2.4.22-ppc-dev.orig/ipc/msg.c 2003-09-14 14:03:26.000000000 +0200 >+++ linux-2.4.22-ppc-dev/ipc/msg.c 2003-09-14 14:07:42.000000000 +0200 >@@ -22,6 +22,7 @@ > #include <linux/init.h> > #include <linux/proc_fs.h> > #include <linux/list.h> >+#include <linux/grsecurity.h> > #include <asm/uaccess.h> > #include "util.h" > >@@ -326,6 +327,9 @@ > msg_unlock(id); > } > up(&msg_ids.sem); >+ >+ gr_log_msgget(ret, msgflg); >+ > return ret; > } > >@@ -560,6 +564,8 @@ > break; > } > case IPC_RMID: >+ gr_log_msgrm(ipcp->uid, ipcp->cuid); >+ > freeque (msqid); > break; > } >diff -Naur linux-2.4.22-ppc-dev.orig/ipc/sem.c linux-2.4.22-ppc-dev/ipc/sem.c >--- linux-2.4.22-ppc-dev.orig/ipc/sem.c 2003-09-14 14:03:26.000000000 +0200 >+++ linux-2.4.22-ppc-dev/ipc/sem.c 2003-09-14 14:07:42.000000000 +0200 >@@ -63,6 +63,7 @@ > #include <linux/init.h> > #include <linux/proc_fs.h> > #include <linux/time.h> >+#include <linux/grsecurity.h> > #include <asm/uaccess.h> > #include "util.h" > >@@ -182,6 +183,9 @@ > } > > up(&sem_ids.sem); >+ >+ gr_log_semget(err, semflg); >+ > return err; > } > >@@ -724,6 +728,8 @@ > > switch(cmd){ > case IPC_RMID: >+ gr_log_semrm(ipcp->uid, ipcp->cuid); >+ > freeary(semid); > err = 0; > break; >diff -Naur linux-2.4.22-ppc-dev.orig/ipc/shm.c linux-2.4.22-ppc-dev/ipc/shm.c >--- linux-2.4.22-ppc-dev.orig/ipc/shm.c 2003-09-14 14:03:26.000000000 +0200 >+++ linux-2.4.22-ppc-dev/ipc/shm.c 2003-09-14 14:07:42.000000000 +0200 >@@ -23,6 +23,7 @@ > #include <linux/mman.h> > #include <linux/proc_fs.h> > #include <asm/uaccess.h> >+#include <linux/grsecurity.h> > > #include "util.h" > >@@ -38,8 +39,21 @@ > 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_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid, >+ const time_t shm_createtime, const uid_t cuid, >+ const int shmid); >+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 +223,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); >@@ -254,6 +271,9 @@ > shm_unlock(id); > } > up(&shm_ids.sem); >+ >+ gr_log_shmget(err, shmflg, size); >+ > return err; > } > >@@ -509,6 +529,9 @@ > err=-EPERM; > goto out_unlock_up; > } >+ >+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid); >+ > if (shp->shm_nattch){ > shp->shm_flags |= SHM_DEST; > /* Do not find it any more */ >@@ -622,9 +645,28 @@ > shm_unlock(shmid); > return -EACCES; > } >+ >+#ifdef CONFIG_GRKERNSEC >+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime, >+ shp->shm_perm.cuid, shmid)) { >+ shm_unlock(shmid); >+ return -EACCES; >+ } >+ >+ 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 -Naur linux-2.4.22-ppc-dev.orig/kernel/capability.c linux-2.4.22-ppc-dev/kernel/capability.c >--- linux-2.4.22-ppc-dev.orig/kernel/capability.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/capability.c 2003-09-14 14:07:42.000000000 +0200 >@@ -7,6 +7,7 @@ > > #include <linux/mm.h> > #include <asm/uaccess.h> >+#include <linux/grsecurity.h> > > kernel_cap_t cap_bset = CAP_INIT_EFF_SET; > >@@ -168,6 +169,10 @@ > target = current; > } > >+ if (gr_handle_chroot_capset(target)) { >+ error = -ESRCH; >+ goto out; >+ } > > /* verify restrictions on target's new Inheritable set */ > if (!cap_issubset(inheritable, >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/exit.c linux-2.4.22-ppc-dev/kernel/exit.c >--- linux-2.4.22-ppc-dev.orig/kernel/exit.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/exit.c 2003-09-14 14:07:42.000000000 +0200 >@@ -16,6 +16,7 @@ > #ifdef CONFIG_BSD_PROCESS_ACCT > #include <linux/acct.h> > #endif >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/pgtable.h> >@@ -439,6 +440,10 @@ > #ifdef CONFIG_BSD_PROCESS_ACCT > acct_process(code); > #endif >+ >+ gr_acl_handle_psacct(tsk, code); >+ gr_acl_handle_exit(); >+ > __exit_mm(tsk); > > lock_kernel(); >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/fork.c linux-2.4.22-ppc-dev/kernel/fork.c >--- linux-2.4.22-ppc-dev.orig/kernel/fork.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/fork.c 2003-09-14 14:07:42.000000000 +0200 >@@ -22,6 +22,7 @@ > #include <linux/namespace.h> > #include <linux/personality.h> > #include <linux/compiler.h> >+#include <linux/grsecurity.h> > > #include <asm/pgtable.h> > #include <asm/pgalloc.h> >@@ -93,6 +94,10 @@ > if (flags & CLONE_PID) > return current->pid; > >+ pid = gr_random_pid(&lastpid_lock); >+ if (pid) >+ return pid; >+ > spin_lock(&lastpid_lock); > beginpid = last_pid; > if((++last_pid) & 0xffff8000) { >@@ -667,6 +672,9 @@ > * friends to set the per-user process limit to something lower > * than the amount of processes root is running. -- Rik > */ >+ >+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes)); >+ > if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur > && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) > goto bad_fork_free; >@@ -751,6 +759,7 @@ > retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); > if (retval) > goto bad_fork_cleanup_namespace; >+ gr_copy_label(p); > p->semundo = NULL; > > /* Our parent execution domain becomes current domain >@@ -836,6 +845,9 @@ > free_uid(p->user); > bad_fork_free: > free_task_struct(p); >+ >+ gr_log_forkfail(retval); >+ > goto fork_out; > } > >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/ksyms.c linux-2.4.22-ppc-dev/kernel/ksyms.c >--- linux-2.4.22-ppc-dev.orig/kernel/ksyms.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/ksyms.c 2003-09-14 14:07:42.000000000 +0200 >@@ -49,6 +49,7 @@ > #include <linux/seq_file.h> > #include <linux/dnotify.h> > #include <linux/crc32.h> >+#include <linux/grsecurity.h> > #include <asm/checksum.h> > > #if defined(CONFIG_PROC_FS) >@@ -600,3 +601,9 @@ > /* To match ksyms with System.map */ > extern const char _end[]; > EXPORT_SYMBOL(_end); >+ >+/* grsecurity */ >+EXPORT_SYMBOL(gr_is_capable); >+EXPORT_SYMBOL(gr_pid_is_chrooted); >+EXPORT_SYMBOL(gr_learn_resource); >+EXPORT_SYMBOL(gr_set_kernel_label); >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/module.c linux-2.4.22-ppc-dev/kernel/module.c >--- linux-2.4.22-ppc-dev.orig/kernel/module.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/module.c 2003-09-14 14:07:42.000000000 +0200 >@@ -900,6 +900,11 @@ > struct module *mod; > int err; > >+#ifdef CONFIG_GRKERNSEC_HIDESYM >+ if (!capable(CAP_SYS_MODULE)) >+ return -EPERM; >+#endif >+ > lock_kernel(); > if (name_user == NULL) > mod = &kernel_module; >@@ -969,6 +974,11 @@ > int i; > struct kernel_sym ksym; > >+#ifdef CONFIG_GRKERNSEC_HIDESYM >+ if (!capable(CAP_SYS_MODULE)) >+ return 0; >+#endif >+ > lock_kernel(); > for (mod = module_list, i = 0; mod; mod = mod->next) { > /* include the count for the module name! */ >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/printk.c linux-2.4.22-ppc-dev/kernel/printk.c >--- linux-2.4.22-ppc-dev.orig/kernel/printk.c 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/printk.c 2003-09-14 14:07:42.000000000 +0200 >@@ -26,6 +26,7 @@ > #include <linux/module.h> > #include <linux/interrupt.h> /* For in_interrupt() */ > #include <linux/config.h> >+#include <linux/grsecurity.h> > #ifdef CONFIG_BOOTX_TEXT > #include <asm/btext.h> > #endif >@@ -296,6 +297,11 @@ > > asmlinkage long sys_syslog(int type, char * buf, int len) > { >+#ifdef CONFIG_GRKERNSEC_DMESG >+ if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg) >+ return -EPERM; >+ else >+#endif > if ((type != 3) && !capable(CAP_SYS_ADMIN)) > return -EPERM; > return do_syslog(type, buf, len); >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/sched.c linux-2.4.22-ppc-dev/kernel/sched.c >--- linux-2.4.22-ppc-dev.orig/kernel/sched.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/sched.c 2003-09-14 14:07:42.000000000 +0200 >@@ -22,6 +22,7 @@ > #include <linux/config.h> > #include <linux/mm.h> > #include <linux/init.h> >+#include <linux/file.h> > #include <linux/smp_lock.h> > #include <linux/nmi.h> > #include <linux/interrupt.h> >@@ -29,6 +30,7 @@ > #include <linux/completion.h> > #include <linux/prefetch.h> > #include <linux/compiler.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/mmu_context.h> >@@ -910,6 +912,9 @@ > return -EPERM; > if (increment < -40) > increment = -40; >+ >+ if (gr_handle_chroot_nice()) >+ return -EPERM; > } > if (increment > 40) > increment = 40; >@@ -1288,12 +1293,21 @@ > > write_lock_irq(&tasklist_lock); > >+#ifdef CONFIG_GRKERNSEC >+ if (this_task->exec_file) { >+ fput(this_task->exec_file); >+ this_task->exec_file = NULL; >+ } >+#endif >+ > /* Reparent to init */ > REMOVE_LINKS(this_task); > this_task->p_pptr = child_reaper; > this_task->p_opptr = child_reaper; > SET_LINKS(this_task); > >+ gr_set_kernel_label(this_task); >+ > /* Set the exit signal to SIGCHLD so we signal init on exit */ > this_task->exit_signal = SIGCHLD; > >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/signal.c linux-2.4.22-ppc-dev/kernel/signal.c >--- linux-2.4.22-ppc-dev.orig/kernel/signal.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/signal.c 2003-09-14 14:08:28.000000000 +0200 >@@ -13,6 +13,8 @@ > #include <linux/smp_lock.h> > #include <linux/init.h> > #include <linux/sched.h> >+#include <linux/fs.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > >@@ -554,6 +556,8 @@ > if (!sig || !t->sig) > goto out_nolock; > >+ gr_log_signal(sig, t); >+ > spin_lock_irqsave(&t->sigmask_lock, flags); > handle_stop_signal(sig, t); > >@@ -603,6 +607,8 @@ > recalc_sigpending(t); > spin_unlock_irqrestore(&t->sigmask_lock, flags); > >+ gr_handle_crash(t, sig); >+ > return send_sig_info(sig, info, t); > } > >@@ -622,9 +628,13 @@ > read_lock(&tasklist_lock); > for_each_task(p) { > if (p->pgrp == pgrp && thread_group_leader(p)) { >- int err = send_sig_info(sig, info, p); >- if (retval) >- retval = err; >+ if (gr_handle_signal(p, sig)) >+ retval = -EPERM; >+ else { >+ int err = send_sig_info(sig, info, p); >+ if (retval) >+ retval = err; >+ } > } > } > read_unlock(&tasklist_lock); >@@ -675,7 +685,10 @@ > if (tg) > p = tg; > } >- error = send_sig_info(sig, info, p); >+ if (gr_handle_signal(p, sig)) >+ error = -EPERM; >+ else >+ error = send_sig_info(sig, info, p); > } > read_unlock(&tasklist_lock); > return error; >@@ -700,10 +713,14 @@ > read_lock(&tasklist_lock); > for_each_task(p) { > if (p->pid > 1 && p != current && thread_group_leader(p)) { >- int err = send_sig_info(sig, info, p); >- ++count; >- if (err != -EPERM) >- retval = err; >+ if (gr_handle_signal(p, sig)) >+ retval = -EPERM; >+ else { >+ int err = send_sig_info(sig, info, p); >+ ++count; >+ if (err != -EPERM) >+ retval = err; >+ } > } > } > read_unlock(&tasklist_lock); >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/sys.c linux-2.4.22-ppc-dev/kernel/sys.c >--- linux-2.4.22-ppc-dev.orig/kernel/sys.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/sys.c 2003-09-14 14:08:44.000000000 +0200 >@@ -4,6 +4,7 @@ > * Copyright (C) 1991, 1992 Linus Torvalds > */ > >+#include <linux/config.h> > #include <linux/module.h> > #include <linux/mm.h> > #include <linux/utsname.h> >@@ -14,6 +15,7 @@ > #include <linux/prctl.h> > #include <linux/init.h> > #include <linux/highuid.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/io.h> >@@ -239,6 +241,12 @@ > } > if (error == -ESRCH) > error = 0; >+ >+ if (gr_handle_chroot_setpriority(p, niceval)) { >+ read_unlock(&tasklist_lock); >+ return -ESRCH; >+ } >+ > if (niceval < p->nice && !capable(CAP_SYS_NICE)) > error = -EACCES; > else >@@ -425,6 +433,9 @@ > if (rgid != (gid_t) -1 || > (egid != (gid_t) -1 && egid != old_rgid)) > current->sgid = new_egid; >+ >+ gr_set_role_label(current, current->uid, new_rgid); >+ > current->fsgid = new_egid; > current->egid = new_egid; > current->gid = new_rgid; >@@ -447,6 +458,9 @@ > current->mm->dumpable=0; > wmb(); > } >+ >+ gr_set_role_label(current, current->uid, gid); >+ > current->gid = current->egid = current->sgid = current->fsgid = gid; > } > else if ((gid == current->gid) || (gid == current->sgid)) >@@ -530,6 +544,9 @@ > current->mm->dumpable = 0; > wmb(); > } >+ >+ gr_set_role_label(current, new_ruid, current->gid); >+ > current->uid = new_ruid; > current->user = new_user; > free_uid(old_user); >@@ -626,6 +643,9 @@ > } else if ((uid != current->uid) && (uid != new_suid)) > return -EPERM; > >+ if (gr_check_crash_uid(uid)) >+ return -EPERM; >+ > if (old_euid != uid) > { > current->mm->dumpable = 0; >@@ -722,8 +742,10 @@ > current->egid = egid; > } > current->fsgid = current->egid; >- if (rgid != (gid_t) -1) >+ if (rgid != (gid_t) -1) { >+ gr_set_role_label(current, current->uid, rgid); > current->gid = rgid; >+ } > if (sgid != (gid_t) -1) > current->sgid = sgid; > return 0; >@@ -1146,6 +1168,10 @@ > if (new_rlim.rlim_cur > new_rlim.rlim_max) > return -EINVAL; > old_rlim = current->rlim + resource; >+ >+ if (old_rlim->rlim_max < old_rlim->rlim_cur) >+ return -EINVAL; >+ > if (((new_rlim.rlim_cur > old_rlim->rlim_max) || > (new_rlim.rlim_max > old_rlim->rlim_max)) && > !capable(CAP_SYS_RESOURCE)) >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/sysctl.c linux-2.4.22-ppc-dev/kernel/sysctl.c >--- linux-2.4.22-ppc-dev.orig/kernel/sysctl.c 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/sysctl.c 2003-09-14 14:07:42.000000000 +0200 >@@ -38,6 +38,15 @@ > #endif > > #if defined(CONFIG_SYSCTL) >+#include <linux/grsecurity.h> >+#include <linux/grinternal.h> >+ >+extern int gr_proc_handler(ctl_table * table, int write, struct file * filp, >+ void * buffer, size_t * lenp); >+extern __u32 gr_handle_sysctl(const ctl_table * table, const void *oldval, >+ const void *newval); >+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; >@@ -125,6 +134,8 @@ > static ctl_table dev_table[]; > extern ctl_table random_table[]; > >+static ctl_table grsecurity_table[]; >+ > /* /proc declarations: */ > > #ifdef CONFIG_PROC_FS >@@ -271,8 +282,191 @@ > {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_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL, >+GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, 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_SIDCAPS, >+GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN, >+GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT, >+GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS, >+GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC, >+GS_FINDTASK, GS_LOCK}; >+ >+static ctl_table grsecurity_table[] = { >+#ifdef CONFIG_GRKERNSEC_LINK >+ {GS_LINK, "linking_restrictions", &grsec_enable_link, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_FIFO >+ {GS_FIFO, "fifo_restrictions", &grsec_enable_fifo, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_EXECVE >+ {GS_EXECVE, "execve_limiting", &grsec_enable_execve, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_EXECLOG >+ {GS_EXECLOG, "exec_logging", &grsec_enable_execlog, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_SIGNAL >+ {GS_SIGNAL, "signal_logging", &grsec_enable_signal, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_FORKFAIL >+ {GS_FORKFAIL, "forkfail_logging", &grsec_enable_forkfail, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_TIME >+ {GS_TIME, "timechange_logging", &grsec_enable_time, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#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_RANDPID >+ {GS_RANDPID, "rand_pids", &grsec_enable_randpid, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDID >+ {GS_RANDID, "rand_ip_ids", &grsec_enable_randid, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDSRC >+ {GS_RANDSRC, "rand_tcp_src_ports", &grsec_enable_randsrc, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDISN >+ {GS_RANDISN, "rand_isns", &grsec_enable_randisn, 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 >+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP >+ {GS_GROUP, "audit_group", &grsec_enable_group, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+ {GS_GID, "audit_gid", >+ &grsec_audit_gid, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR >+ {GS_ACHDIR, "audit_chdir", &grsec_enable_chdir, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT >+ {GS_AMOUNT, "audit_mount", &grsec_enable_mount, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC >+ {GS_AIPC, "audit_ipc", &grsec_enable_audit_ipc, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_DMESG >+ {GS_AIPC, "dmesg", &grsec_enable_dmesg, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDRPC >+ {GS_RANDRPC, "rand_rpc", &grsec_enable_randrpc, sizeof (int), >+ 0600, NULL, &proc_dointvec}, >+#endif >+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK >+ {GS_FINDTASK, "chroot_findtask", &grsec_enable_chroot_findtask, >+ 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, >@@ -411,6 +605,11 @@ > > static inline int ctl_perm(ctl_table *table, int op) > { >+ if (gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op)) >+ return -EACCES; >+ if (gr_handle_chroot_sysctl(op)) >+ return -EACCES; >+ > return test_perm(table->mode, op); > } > >@@ -444,6 +643,10 @@ > table = table->child; > goto repeat; > } >+ >+ if (!gr_handle_sysctl(table, oldval, newval)) >+ return -EACCES; >+ > error = do_sysctl_strategy(table, name, nlen, > oldval, oldlenp, > newval, newlen, context); >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/time.c linux-2.4.22-ppc-dev/kernel/time.c >--- linux-2.4.22-ppc-dev.orig/kernel/time.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/time.c 2003-09-14 14:07:43.000000000 +0200 >@@ -27,6 +27,7 @@ > #include <linux/mm.h> > #include <linux/timex.h> > #include <linux/smp_lock.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > >@@ -89,6 +90,9 @@ > time_maxerror = NTP_PHASE_LIMIT; > time_esterror = NTP_PHASE_LIMIT; > write_unlock_irq(&xtime_lock); >+ >+ gr_log_timechange(); >+ > return 0; > } > >@@ -167,6 +171,8 @@ > * globally block out interrupts when it runs. > */ > do_settimeofday(tv); >+ >+ gr_log_timechange(); > } > return 0; > } >diff -Naur linux-2.4.22-ppc-dev.orig/kernel/timer.c linux-2.4.22-ppc-dev/kernel/timer.c >--- linux-2.4.22-ppc-dev.orig/kernel/timer.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/kernel/timer.c 2003-09-14 14:07:43.000000000 +0200 >@@ -541,6 +541,9 @@ > > psecs = (p->times.tms_utime += user); > psecs += (p->times.tms_stime += system); >+ >+ gr_learn_resource(p, RLIMIT_CPU, psecs / HZ); >+ > if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) { > /* Send SIGXCPU every second.. */ > if (!(psecs % HZ)) >diff -Naur linux-2.4.22-ppc-dev.orig/mm/filemap.c linux-2.4.22-ppc-dev/mm/filemap.c >--- linux-2.4.22-ppc-dev.orig/mm/filemap.c 2003-09-14 14:08:03.000000000 +0200 >+++ linux-2.4.22-ppc-dev/mm/filemap.c 2003-09-14 14:07:43.000000000 +0200 >@@ -2345,6 +2345,12 @@ > } > if (!mapping->a_ops->readpage) > return -ENOEXEC; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (current->flags & PF_PAX_PAGEEXEC) >+ vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; >+#endif >+ > UPDATE_ATIME(inode); > vma->vm_ops = &generic_file_vm_ops; > return 0; >@@ -2629,6 +2635,7 @@ > error = -EIO; > rlim_rss = current->rlim ? current->rlim[RLIMIT_RSS].rlim_cur : > LONG_MAX; /* default: see resource.h */ >+ gr_learn_resource(current, RLIMIT_RSS, vma->vm_mm->rss + (end - start)); > if ((vma->vm_mm->rss + (end - start)) > rlim_rss) > return error; > >@@ -3104,6 +3111,7 @@ > err = -EFBIG; > > if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) { >+ gr_learn_resource(current, RLIMIT_FSIZE, pos); > if (pos >= limit) { > send_sig(SIGXFSZ, current, 0); > goto out; >@@ -3139,6 +3147,7 @@ > */ > > if (!S_ISBLK(inode->i_mode)) { >+ gr_learn_resource(current, RLIMIT_FSIZE, *count + (u32)pos); > if (pos >= inode->i_sb->s_maxbytes) > { > if (*count || pos > inode->i_sb->s_maxbytes) { >diff -Naur linux-2.4.22-ppc-dev.orig/mm/memory.c linux-2.4.22-ppc-dev/mm/memory.c >--- linux-2.4.22-ppc-dev.orig/mm/memory.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/mm/memory.c 2003-09-14 14:07:43.000000000 +0200 >@@ -925,6 +925,65 @@ > establish_pte(vma, address, page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot)))); > } > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+/* PaX: if vma is mirrored, synchronize the mirror's PTE >+ * >+ * mm->page_table_lock is held on entry and is not released on exit or inside >+ * to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc) >+ */ >+static void pax_mirror_fault(struct mm_struct *mm, struct vm_area_struct * vma, >+ unsigned long address, pte_t *pte) >+{ >+ unsigned long address_m; >+ struct vm_area_struct * vma_m = NULL; >+ pte_t * pte_m, entry_m; >+ struct page * page_m; >+ >+ if (!(vma->vm_flags & VM_MIRROR)) >+ return; >+ >+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data; >+ vma_m = find_vma(mm, address_m); >+ if (!vma_m || vma_m->vm_start != address_m) >+ return; >+ >+ address_m = address + (unsigned long)vma->vm_private_data; >+ >+ { >+ pgd_t *pgd_m; >+ pmd_t *pmd_m; >+ >+ pgd_m = pgd_offset(mm, address_m); >+ pmd_m = pmd_offset(pgd_m, address_m); >+ pte_m = pte_offset(pmd_m, address_m); >+ } >+ >+ if (pte_present(*pte_m)) { >+ flush_cache_page(vma_m, address_m); >+ flush_icache_page(vma_m, pte_page(*pte_m)); >+ } >+ entry_m = ptep_get_and_clear(pte_m); >+ if (pte_present(entry_m)) >+ flush_tlb_page(vma_m, address_m); >+ >+ if (pte_none(entry_m)) { >+ ++mm->rss; >+ } else if (pte_present(entry_m)) { >+ page_cache_release(pte_page(entry_m)); >+ } else { >+ free_swap_and_cache(pte_to_swp_entry(entry_m)); >+ ++mm->rss; >+ } >+ >+ page_m = pte_page(*pte); >+ page_cache_get(page_m); >+ entry_m = mk_pte(page_m, vma_m->vm_page_prot); >+ if (pte_write(*pte)) >+ entry_m = pte_mkdirty(pte_mkwrite(entry_m)); >+ establish_pte(vma_m, address_m, pte_m, entry_m); >+} >+#endif >+ > /* > * This routine handles present pages, when users try to write > * to a shared page. It is done by copying the page to a new address >@@ -988,6 +1047,11 @@ > > /* Free the old page.. */ > new_page = old_page; >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ pax_mirror_fault(mm, vma, address, page_table); >+#endif >+ > } > spin_unlock(&mm->page_table_lock); > page_cache_release(new_page); >@@ -1065,6 +1129,7 @@ > > do_expand: > limit = current->rlim[RLIMIT_FSIZE].rlim_cur; >+ gr_learn_resource(current, RLIMIT_FSIZE, offset); > if (limit != RLIM_INFINITY && offset > limit) > goto out_sig; > if (offset > inode->i_sb->s_maxbytes) >@@ -1178,6 +1243,11 @@ > > /* No need to invalidate - it was non-present before */ > update_mmu_cache(vma, address, pte); >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ pax_mirror_fault(mm, vma, address, page_table); >+#endif >+ > spin_unlock(&mm->page_table_lock); > return ret; > } >@@ -1223,6 +1293,11 @@ > > /* No need to invalidate - it was non-present before */ > update_mmu_cache(vma, addr, entry); >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ pax_mirror_fault(mm, vma, addr, page_table); >+#endif >+ > spin_unlock(&mm->page_table_lock); > return 1; /* Minor fault */ > >@@ -1303,6 +1378,11 @@ > > /* no need to invalidate: a not-present page shouldn't be cached */ > update_mmu_cache(vma, address, entry); >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ pax_mirror_fault(mm, vma, address, page_table); >+#endif >+ > spin_unlock(&mm->page_table_lock); > return 2; /* Major fault */ > } >@@ -1367,6 +1447,11 @@ > pgd_t *pgd; > pmd_t *pmd; > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ unsigned long address_m = 0UL; >+ struct vm_area_struct * vma_m = NULL; >+#endif >+ > current->state = TASK_RUNNING; > pgd = pgd_offset(mm, address); > >@@ -1375,6 +1460,47 @@ > * and the SMP-safe atomic PTE updates. > */ > spin_lock(&mm->page_table_lock); >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (vma->vm_flags & VM_MIRROR) { >+ pgd_t *pgd_m; >+ pmd_t *pmd_m; >+ pte_t *pte_m; >+ >+ address_m = vma->vm_start + (unsigned long)vma->vm_private_data; >+ vma_m = find_vma(mm, address_m); >+ >+ /* PaX: sanity checks */ >+ if (!vma_m) { >+ spin_unlock(&mm->page_table_lock); >+ printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n", >+ address, vma, address_m, vma_m); >+ return 0; >+ } else if (!(vma_m->vm_flags & VM_MIRROR) || >+ vma_m->vm_start != address_m || >+ vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start) >+ { >+ spin_unlock(&mm->page_table_lock); >+ printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n", >+ address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end); >+ return 0; >+ } >+ >+ address_m = address + (unsigned long)vma->vm_private_data; >+ pgd_m = pgd_offset(mm, address_m); >+ pmd_m = pmd_alloc(mm, pgd_m, address_m); >+ if (!pmd_m) { >+ spin_unlock(&mm->page_table_lock); >+ return -1; >+ } >+ pte_m = pte_alloc(mm, pmd_m, address_m); >+ if (!pte_m) { >+ spin_unlock(&mm->page_table_lock); >+ return -1; >+ } >+ } >+#endif >+ > pmd = pmd_alloc(mm, pgd, address); > > if (pmd) { >diff -Naur linux-2.4.22-ppc-dev.orig/mm/mlock.c linux-2.4.22-ppc-dev/mm/mlock.c >--- linux-2.4.22-ppc-dev.orig/mm/mlock.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/mm/mlock.c 2003-09-14 14:07:43.000000000 +0200 >@@ -114,9 +114,35 @@ > return 0; > } > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+static int __mlock_fixup(struct vm_area_struct * vma, >+ unsigned long start, unsigned long end, unsigned int newflags); > static int mlock_fixup(struct vm_area_struct * vma, > unsigned long start, unsigned long end, unsigned int newflags) > { >+ if (vma->vm_flags & VM_MIRROR) { >+ struct vm_area_struct * vma_m; >+ unsigned long start_m, end_m; >+ >+ start_m = vma->vm_start + (unsigned long)vma->vm_private_data; >+ vma_m = find_vma(vma->vm_mm, start_m); >+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) { >+ start_m = start + (unsigned long)vma->vm_private_data; >+ end_m = end + (unsigned long)vma->vm_private_data; >+ __mlock_fixup(vma_m, start_m, end_m, newflags); >+ } else >+ printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start); >+ } >+ return __mlock_fixup(vma, start, end, newflags); >+} >+ >+static int __mlock_fixup(struct vm_area_struct * vma, >+ unsigned long start, unsigned long end, unsigned int newflags) >+#else >+static int mlock_fixup(struct vm_area_struct * vma, >+ unsigned long start, unsigned long end, unsigned int newflags) >+#endif >+{ > int pages, retval; > > if (newflags == vma->vm_flags) >@@ -209,6 +235,7 @@ > lock_limit >>= PAGE_SHIFT; > > /* check against resource limits */ >+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked); > if (locked > lock_limit) > goto out; > >@@ -276,6 +303,7 @@ > lock_limit >>= PAGE_SHIFT; > > ret = -ENOMEM; >+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm); > if (current->mm->total_vm > lock_limit) > goto out; > >diff -Naur linux-2.4.22-ppc-dev.orig/mm/mmap.c linux-2.4.22-ppc-dev/mm/mmap.c >--- linux-2.4.22-ppc-dev.orig/mm/mmap.c 2003-09-14 14:06:54.000000000 +0200 >+++ linux-2.4.22-ppc-dev/mm/mmap.c 2003-09-14 14:07:43.000000000 +0200 >@@ -14,6 +14,8 @@ > #include <linux/file.h> > #include <linux/fs.h> > #include <linux/personality.h> >+#include <linux/random.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/pgalloc.h> >@@ -169,6 +171,7 @@ > > /* Check against rlimit.. */ > rlim = current->rlim[RLIMIT_DATA].rlim_cur; >+ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data); > if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim) > goto out; > >@@ -206,6 +209,11 @@ > _trans(prot, PROT_WRITE, VM_WRITE) | > _trans(prot, PROT_EXEC, VM_EXEC); > flag_bits = >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ _trans(flags, MAP_MIRROR, VM_MIRROR) | >+#endif >+ > _trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN) | > _trans(flags, MAP_DENYWRITE, VM_DENYWRITE) | > _trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE); >@@ -401,6 +409,28 @@ > int error; > rb_node_t ** rb_link, * rb_parent; > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ struct vm_area_struct * vma_m = NULL; >+ >+ if (flags & MAP_MIRROR) { >+ /* PaX: sanity checks, to be removed when proved to be stable */ >+ if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE)) >+ return -EINVAL; >+ >+ vma_m = find_vma(mm, pgoff); >+ >+ if (!vma_m || >+ vma_m->vm_start != pgoff || >+ (vma_m->vm_flags & VM_MIRROR) || >+ (!(vma_m->vm_flags & VM_WRITE) && (prot & PROT_WRITE))) >+ return -EINVAL; >+ >+ file = vma_m->vm_file; >+ pgoff = vma_m->vm_pgoff; >+ len = vma_m->vm_end - vma_m->vm_start; >+ } >+#endif >+ > if (file && (!file->f_op || !file->f_op->mmap)) > return -ENODEV; > >@@ -433,10 +463,32 @@ > */ > vm_flags = calc_vm_flags(prot,flags) | mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC; > >+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) >+ if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) { >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+ if (current->flags & PF_PAX_MPROTECT) { >+ if (!file || (prot & PROT_WRITE)) >+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC); >+ else >+ vm_flags &= ~VM_MAYWRITE; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_RANDEXEC >+ if (file && (flags & MAP_MIRROR) && (vm_flags & VM_EXEC)) >+ vma_m->vm_flags &= ~VM_MAYWRITE; >+#endif >+ >+ } >+#endif >+ >+ } >+#endif >+ > /* mlock MCL_FUTURE? */ > if (vm_flags & VM_LOCKED) { > unsigned long locked = mm->locked_vm << PAGE_SHIFT; > locked += len; >+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked); > if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) > return -EAGAIN; > } >@@ -481,6 +533,9 @@ > } > } > >+ if (!gr_acl_handle_mmap(file, prot)) >+ return -EACCES; >+ > /* Clear old maps */ > munmap_back: > vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent); >@@ -491,10 +546,16 @@ > } > > /* Check against address space limit. */ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (!(vm_flags & VM_MIRROR)) { >+#endif >+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len); > if ((mm->total_vm << PAGE_SHIFT) + len > > current->rlim[RLIMIT_AS].rlim_cur) > return -ENOMEM; >- >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ } >+#endif > /* Private writable mapping? Check memory availability.. */ > if ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE && > !(flags & MAP_NORESERVE) && >@@ -518,6 +579,13 @@ > vma->vm_start = addr; > vma->vm_end = addr + len; > vma->vm_flags = vm_flags; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if ((file || !(current->flags & PF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE))) >+ vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & 0x0f]; >+ else >+#endif >+ > vma->vm_page_prot = protection_map[vm_flags & 0x0f]; > vma->vm_ops = NULL; > vma->vm_pgoff = pgoff; >@@ -546,6 +614,14 @@ > goto free_vma; > } > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (flags & MAP_MIRROR) { >+ vma_m->vm_flags |= VM_MIRROR; >+ vma_m->vm_private_data = (void *)(vma->vm_start - vma_m->vm_start); >+ vma->vm_private_data = (void *)(vma_m->vm_start - vma->vm_start); >+ } >+#endif >+ > /* Can addr have changed?? > * > * Answer: Yes, several device drivers can do it in their >@@ -581,6 +657,9 @@ > atomic_inc(&file->f_dentry->d_inode->i_writecount); > > out: >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (!(flags & MAP_MIRROR)) >+#endif > mm->total_vm += len >> PAGE_SHIFT; > if (vm_flags & VM_LOCKED) { > mm->locked_vm += len >> PAGE_SHIFT; >@@ -617,20 +696,49 @@ > { > struct vm_area_struct *vma; > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((current->flags & PF_PAX_SEGMEXEC) && len > SEGMEXEC_TASK_SIZE) >+ return -ENOMEM; >+ else >+#endif >+ > if (len > TASK_SIZE) > return -ENOMEM; > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ if (!(current->flags & PF_PAX_RANDMMAP) || !filp) >+#endif >+ > if (addr) { > addr = PAGE_ALIGN(addr); > vma = find_vma(current->mm, addr); >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr) >+ return -ENOMEM; >+#endif >+ > if (TASK_SIZE - len >= addr && > (!vma || addr + len <= vma->vm_start)) > return addr; > } > addr = PAGE_ALIGN(TASK_UNMAPPED_BASE); > >+#ifdef CONFIG_GRKERNSEC_PAX_RANDMMAP >+ /* PaX: randomize base address if requested */ >+ if (current->flags & PF_PAX_RANDMMAP) >+ addr += current->mm->delta_mmap; >+#endif >+ > for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) { > /* At this point: (!vma || addr < vma->vm_end). */ >+ >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((current->flags & PF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE-len < addr) >+ return -ENOMEM; >+ else >+#endif >+ > unsigned long __heap_stack_gap; > if (TASK_SIZE - len < addr) > return -ENOMEM; >@@ -799,6 +907,9 @@ > struct vm_area_struct *mpnt; > unsigned long end = addr + len; > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (!(area->vm_flags & VM_MIRROR)) >+#endif > area->vm_mm->total_vm -= len >> PAGE_SHIFT; > if (area->vm_flags & VM_LOCKED) > area->vm_mm->locked_vm -= len >> PAGE_SHIFT; >@@ -924,6 +1035,83 @@ > } > } > >+static inline struct vm_area_struct *unmap_vma(struct mm_struct *mm, >+ unsigned long addr, size_t len, struct vm_area_struct *mpnt, >+ struct vm_area_struct *extra) >+{ >+ unsigned long st, end, size; >+ struct file *file = NULL; >+ >+ st = addr < mpnt->vm_start ? mpnt->vm_start : addr; >+ end = addr+len; >+ end = end > mpnt->vm_end ? mpnt->vm_end : end; >+ size = end - st; >+ >+ if (mpnt->vm_flags & VM_DENYWRITE && >+ (st != mpnt->vm_start || end != mpnt->vm_end) && >+ (file = mpnt->vm_file) != NULL) { >+ atomic_dec(&file->f_dentry->d_inode->i_writecount); >+ } >+ remove_shared_vm_struct(mpnt); >+ zap_page_range(mm, st, size); >+ >+ /* >+ * Fix the mapping, and free the old area if it wasn't reused. >+ */ >+ extra = unmap_fixup(mm, mpnt, st, size, extra); >+ if (file) >+ atomic_inc(&file->f_dentry->d_inode->i_writecount); >+ return extra; >+} >+ >+static struct vm_area_struct *unmap_vma_list(struct mm_struct *mm, >+ unsigned long addr, size_t len, struct vm_area_struct *free, >+ struct vm_area_struct *extra, struct vm_area_struct *prev) >+{ >+ struct vm_area_struct *mpnt; >+ >+ /* Ok - we have the memory areas we should free on the 'free' list, >+ * so release them, and unmap the page range.. >+ * If the one of the segments is only being partially unmapped, >+ * it will put new vm_area_struct(s) into the address space. >+ * In that case we have to be careful with VM_DENYWRITE. >+ */ >+ while ((mpnt = free) != NULL) { >+ free = free->vm_next; >+ extra = unmap_vma(mm, addr, len, mpnt, extra); >+ } >+ >+ free_pgtables(mm, prev, addr, addr+len); >+ >+ return extra; >+} >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+static struct vm_area_struct *unmap_vma_mirror_list(struct mm_struct *mm, >+ unsigned long addr, size_t len, struct vm_area_struct *free_m, >+ struct vm_area_struct *extra_m) >+{ >+ struct vm_area_struct *mpnt, *prev; >+ >+ while ((mpnt = free_m) != NULL) { >+ unsigned long addr_m, start, end; >+ >+ free_m = free_m->vm_next; >+ >+ addr_m = addr - (unsigned long)mpnt->vm_private_data; >+ start = addr_m < mpnt->vm_start ? mpnt->vm_start : addr_m; >+ end = addr_m+len; >+ end = end > mpnt->vm_end ? mpnt->vm_end : end; >+ find_vma_prev(mm, mpnt->vm_start, &prev); >+ extra_m = unmap_vma(mm, addr_m, len, mpnt, extra_m); >+ >+ free_pgtables(mm, prev, start, end); >+ } >+ >+ return extra_m; >+} >+#endif >+ > /* Munmap is split into 2 main parts -- this part which finds > * what needs doing, and the areas themselves, which do the > * work. This now handles partial unmappings. >@@ -933,6 +1121,10 @@ > { > struct vm_area_struct *mpnt, *prev, **npp, *free, *extra; > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ struct vm_area_struct *free_m, *extra_m; >+#endif >+ > if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr) > return -EINVAL; > >@@ -965,60 +1157,69 @@ > if (!extra) > return -ENOMEM; > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) { >+ extra_m = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); >+ if (!extra_m) { >+ kmem_cache_free(vm_area_cachep, extra); >+ return -ENOMEM; >+ } >+ } else >+ extra_m = NULL; >+ >+ free_m = NULL; >+#endif >+ > npp = (prev ? &prev->vm_next : &mm->mmap); > free = NULL; > spin_lock(&mm->page_table_lock); > for ( ; mpnt && mpnt->vm_start < addr+len; mpnt = *npp) { >+ mm->map_count--; > *npp = mpnt->vm_next; > mpnt->vm_next = free; > free = mpnt; > rb_erase(&mpnt->vm_rb, &mm->mm_rb); >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (free->vm_flags & VM_MIRROR) { >+ struct vm_area_struct *mpnt_m, *prev_m, **npp_m; >+ unsigned long addr_m = free->vm_start + (unsigned long)free->vm_private_data; >+ >+ mm->mmap_cache = NULL; /* Kill the cache. */ >+ mpnt_m = find_vma_prev(mm, addr_m, &prev_m); >+ if (mpnt_m && mpnt_m->vm_start == addr_m && (mpnt_m->vm_flags & VM_MIRROR)) { >+ mm->map_count--; >+ npp_m = (prev_m ? &prev_m->vm_next : &mm->mmap); >+ *npp_m = mpnt_m->vm_next; >+ mpnt_m->vm_next = free_m; >+ free_m = mpnt_m; >+ rb_erase(&mpnt_m->vm_rb, &mm->mm_rb); >+ } else >+ printk("PAX: VMMIRROR: munmap bug in %s, %08lx\n", current->comm, free->vm_start); >+ } >+#endif >+ > } > mm->mmap_cache = NULL; /* Kill the cache. */ > spin_unlock(&mm->page_table_lock); > >- /* Ok - we have the memory areas we should free on the 'free' list, >- * so release them, and unmap the page range.. >- * If the one of the segments is only being partially unmapped, >- * it will put new vm_area_struct(s) into the address space. >- * In that case we have to be careful with VM_DENYWRITE. >- */ >- while ((mpnt = free) != NULL) { >- unsigned long st, end, size; >- struct file *file = NULL; >- >- free = free->vm_next; >+ extra = unmap_vma_list(mm, addr, len, free, extra, prev); > >- st = addr < mpnt->vm_start ? mpnt->vm_start : addr; >- end = addr+len; >- end = end > mpnt->vm_end ? mpnt->vm_end : end; >- size = end - st; >- >- if (mpnt->vm_flags & VM_DENYWRITE && >- (st != mpnt->vm_start || end != mpnt->vm_end) && >- (file = mpnt->vm_file) != NULL) { >- atomic_dec(&file->f_dentry->d_inode->i_writecount); >- } >- remove_shared_vm_struct(mpnt); >- mm->map_count--; >- >- zap_page_range(mm, st, size); >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ extra_m = unmap_vma_mirror_list(mm, addr, len, free_m, extra_m); >+#endif > >- /* >- * Fix the mapping, and free the old area if it wasn't reused. >- */ >- extra = unmap_fixup(mm, mpnt, st, size, extra); >- if (file) >- atomic_inc(&file->f_dentry->d_inode->i_writecount); >- } > validate_mm(mm); > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (extra_m) >+ kmem_cache_free(vm_area_cachep, extra_m); >+#endif >+ > /* Release the extra vma struct if it wasn't used */ > if (extra) > kmem_cache_free(vm_area_cachep, extra); > >- free_pgtables(mm, prev, addr, addr+len); >- > return 0; > } > >@@ -1027,8 +1228,15 @@ > int ret; > struct mm_struct *mm = current->mm; > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((current->flags & PF_PAX_SEGMEXEC) && >+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len)) >+ return -EINVAL; >+#endif >+ > down_write(&mm->mmap_sem); > ret = do_munmap(mm, addr, len); >+ > up_write(&mm->mmap_sem); > return ret; > } >@@ -1055,6 +1263,7 @@ > if (mm->def_flags & VM_LOCKED) { > unsigned long locked = mm->locked_vm << PAGE_SHIFT; > locked += len; >+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked); > if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) > return -EAGAIN; > } >@@ -1071,6 +1280,7 @@ > } > > /* Check against address space limits *after* clearing old maps... */ >+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len); > if ((mm->total_vm << PAGE_SHIFT) + len > > current->rlim[RLIMIT_AS].rlim_cur) > return -ENOMEM; >@@ -1083,6 +1293,17 @@ > > flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags; > >+#if defined(CONFIG_GRKERNSEC_PAX_PAGEEXEC) || defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) >+ if (current->flags & (PF_PAX_PAGEEXEC | PF_PAX_SEGMEXEC)) { >+ flags &= ~VM_EXEC; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+ if (current->flags & PF_PAX_MPROTECT) >+ flags &= ~VM_MAYEXEC; >+#endif >+ >+ } >+#endif > /* Can we just expand an old anonymous mapping? */ > if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags)) > goto out; >@@ -1098,6 +1319,12 @@ > vma->vm_start = addr; > vma->vm_end = addr + len; > vma->vm_flags = flags; >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (!(current->flags & PF_PAX_PAGEEXEC) && (flags & (VM_READ|VM_WRITE))) >+ vma->vm_page_prot = protection_map[(flags | VM_EXEC) & 0x0f]; >+ else >+#endif > vma->vm_page_prot = protection_map[flags & 0x0f]; > vma->vm_ops = NULL; > vma->vm_pgoff = 0; >diff -Naur linux-2.4.22-ppc-dev.orig/mm/mprotect.c linux-2.4.22-ppc-dev/mm/mprotect.c >--- linux-2.4.22-ppc-dev.orig/mm/mprotect.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/mm/mprotect.c 2003-09-14 14:07:43.000000000 +0200 >@@ -7,6 +7,12 @@ > #include <linux/smp_lock.h> > #include <linux/shm.h> > #include <linux/mman.h> >+#include <linux/grsecurity.h> >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+#include <linux/elf.h> >+#include <linux/fs.h> >+#endif > > #include <asm/uaccess.h> > #include <asm/pgalloc.h> >@@ -236,9 +242,40 @@ > return 0; > } > >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev, >+ unsigned long start, unsigned long end, unsigned int newflags); >+ > static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev, > unsigned long start, unsigned long end, unsigned int newflags) > { >+ if (vma->vm_flags & VM_MIRROR) { >+ struct vm_area_struct * vma_m, * prev_m; >+ unsigned long start_m, end_m; >+ >+ start_m = vma->vm_start + (unsigned long)vma->vm_private_data; >+ vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m); >+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) { >+ start_m = start + (unsigned long)vma->vm_private_data; >+ end_m = end + (unsigned long)vma->vm_private_data; >+ if ((current->flags & PF_PAX_SEGMEXEC) && !(newflags & VM_EXEC)) >+ __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC)); >+ else >+ __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags); >+ } else >+ printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start); >+ } >+ >+ return __mprotect_fixup(vma, pprev, start, end, newflags); >+} >+ >+static int __mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev, >+ unsigned long start, unsigned long end, unsigned int newflags) >+#else >+static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev, >+ unsigned long start, unsigned long end, unsigned int newflags) >+#endif >+{ > pgprot_t newprot; > int error; > >@@ -246,6 +283,12 @@ > *pprev = vma; > return 0; > } >+ >+#ifdef CONFIG_GRKERNSEC_PAX_PAGEEXEC >+ if (!(current->flags & PF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE))) >+ newprot = protection_map[(newflags | VM_EXEC) & 0xf]; >+ else >+#endif > newprot = protection_map[newflags & 0xf]; > if (start == vma->vm_start) { > if (end == vma->vm_end) >@@ -264,6 +307,68 @@ > return 0; > } > >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+/* PaX: non-PIC ELF libraries need relocations on their executable segments >+ * therefore we'll grant them VM_MAYWRITE once during their life. >+ * >+ * The checks favor ld-linux.so behaviour which operates on a per ELF segment >+ * basis because we want to allow the common case and not the special ones. >+ */ >+static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start) >+{ >+ struct elfhdr elf_h; >+ struct elf_phdr elf_p, p_dyn; >+ elf_dyn dyn; >+ unsigned long i, j = 65536UL / sizeof(struct elf_phdr); >+ >+#ifndef CONFIG_GRKERNSEC_PAX_NOELFRELOCS >+ if ((vma->vm_start != start) || >+ !vma->vm_file || >+ !(vma->vm_flags & VM_MAYEXEC) || >+ (vma->vm_flags & VM_MAYNOTWRITE)) >+#endif >+ >+ return; >+ >+ if (0 > kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) || >+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) || >+ >+#ifdef CONFIG_GRKERNSEC_PAX_ETEXECRELOCS >+ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) || >+#else >+ elf_h.e_type != ET_DYN || >+#endif >+ >+ !elf_check_arch(&elf_h) || >+ elf_h.e_phentsize != sizeof(struct elf_phdr) || >+ elf_h.e_phnum > j) >+ return; >+ >+ for (i = 0UL; i < elf_h.e_phnum; i++) { >+ if (0 > kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p))) >+ return; >+ if (elf_p.p_type == PT_DYNAMIC) { >+ p_dyn = elf_p; >+ j = i; >+ } >+ } >+ if (elf_h.e_phnum <= j) >+ return; >+ >+ i = 0UL; >+ do { >+ if (0 > kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn))) >+ return; >+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) { >+ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE; >+ return; >+ } >+ i++; >+ } while (dyn.d_tag != DT_NULL); >+ return; >+} >+#endif >+ > asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot) > { > unsigned long nstart, end, tmp; >@@ -288,6 +393,16 @@ > if (!vma || vma->vm_start > start) > goto out; > >+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) { >+ error = -EACCES; >+ goto out; >+ } >+ >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+ if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE)) >+ pax_handle_maywrite(vma, start); >+#endif >+ > for (nstart = start ; ; ) { > unsigned int newflags; > int last = 0; >@@ -300,6 +415,12 @@ > goto out; > } > >+#ifdef CONFIG_GRKERNSEC_PAX_MPROTECT >+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */ >+ if ((current->flags & PF_PAX_MPROTECT) && (prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE)) >+ newflags &= ~VM_MAYWRITE; >+#endif >+ > if (vma->vm_end > end) { > error = mprotect_fixup(vma, &prev, nstart, end, newflags); > goto out; >@@ -332,6 +453,7 @@ > prev->vm_mm->map_count--; > } > out: >+ > up_write(¤t->mm->mmap_sem); > return error; > } >diff -Naur linux-2.4.22-ppc-dev.orig/mm/mremap.c linux-2.4.22-ppc-dev/mm/mremap.c >--- linux-2.4.22-ppc-dev.orig/mm/mremap.c 2003-09-14 14:03:10.000000000 +0200 >+++ linux-2.4.22-ppc-dev/mm/mremap.c 2003-09-14 14:07:43.000000000 +0200 >@@ -193,7 +193,9 @@ > } > > do_munmap(current->mm, addr, old_len); >- >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (!(new_vma->vm_flags & VM_MIRROR)) >+#endif > current->mm->total_vm += new_len >> PAGE_SHIFT; > if (vm_locked) { > current->mm->locked_vm += new_len >> PAGE_SHIFT; >@@ -232,6 +234,13 @@ > old_len = PAGE_ALIGN(old_len); > new_len = PAGE_ALIGN(new_len); > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((current->flags & PF_PAX_SEGMEXEC) && >+ (new_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-new_len || >+ old_len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-old_len)) >+ goto out; >+#endif >+ > /* new_addr is only valid if MREMAP_FIXED is specified */ > if (flags & MREMAP_FIXED) { > if (new_addr & ~PAGE_MASK) >@@ -242,6 +251,12 @@ > if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) > goto out; > >+#ifdef CONFIG_GRKERNSEC_PAX_SEGMEXEC >+ if ((current->flags & PF_PAX_SEGMEXEC) && >+ (new_len > SEGMEXEC_TASK_SIZE || new_addr > SEGMEXEC_TASK_SIZE-new_len)) >+ goto out; >+#endif >+ > /* Check if the location we're moving into overlaps the > * old location at all, and fail if it does. > */ >@@ -272,6 +287,13 @@ > vma = find_vma(current->mm, addr); > if (!vma || vma->vm_start > addr) > goto out; >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if ((current->flags & (PF_PAX_SEGMEXEC | PF_PAX_RANDEXEC)) && >+ (vma->vm_flags & VM_MIRROR)) >+ return -EINVAL; >+#endif >+ > /* We can't remap across vm area boundaries */ > if (old_len > vma->vm_end - addr) > goto out; >@@ -283,13 +305,22 @@ > unsigned long locked = current->mm->locked_vm << PAGE_SHIFT; > locked += new_len - old_len; > ret = -EAGAIN; >+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked); > if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur) > goto out; > } > ret = -ENOMEM; >+ >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (!(vma->vm_flags & VM_MIRROR)) { >+#endif >+ gr_learn_resource(current, RLIMIT_AS, (current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)); > if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len) > > current->rlim[RLIMIT_AS].rlim_cur) > goto out; >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ } >+#endif > /* Private writable mapping? Check memory availability.. */ > if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE && > !(flags & MAP_NORESERVE) && >@@ -311,6 +342,9 @@ > spin_lock(&vma->vm_mm->page_table_lock); > vma->vm_end = addr + new_len; > spin_unlock(&vma->vm_mm->page_table_lock); >+#if defined(CONFIG_GRKERNSEC_PAX_SEGMEXEC) || defined(CONFIG_GRKERNSEC_PAX_RANDEXEC) >+ if (!(vma->vm_flags & VM_MIRROR)) >+#endif > current->mm->total_vm += pages; > if (vma->vm_flags & VM_LOCKED) { > current->mm->locked_vm += pages; >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/af_inet.c linux-2.4.22-ppc-dev/net/ipv4/af_inet.c >--- linux-2.4.22-ppc-dev.orig/net/ipv4/af_inet.c 2003-09-14 14:03:23.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/ipv4/af_inet.c 2003-09-14 14:07:43.000000000 +0200 >@@ -83,6 +83,7 @@ > #include <linux/init.h> > #include <linux/poll.h> > #include <linux/netfilter_ipv4.h> >+#include <linux/grsecurity.h> > > #include <asm/uaccess.h> > #include <asm/system.h> >@@ -374,7 +375,12 @@ > else > sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT; > >- sk->protinfo.af_inet.id = 0; >+#ifdef CONFIG_GRKERNSEC_RANDID >+ if(grsec_enable_randid) >+ sk->protinfo.af_inet.id = htons(ip_randomid()); >+ else >+#endif >+ sk->protinfo.af_inet.id = 0; > > sock_init_data(sock,sk); > >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/icmp.c linux-2.4.22-ppc-dev/net/ipv4/icmp.c >--- linux-2.4.22-ppc-dev.orig/net/ipv4/icmp.c 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/ipv4/icmp.c 2003-09-14 14:07:43.000000000 +0200 >@@ -87,6 +87,8 @@ > #include <linux/errno.h> > #include <linux/timer.h> > #include <linux/init.h> >+#include <linux/grsecurity.h> >+ > #include <asm/system.h> > #include <asm/uaccess.h> > #include <net/checksum.h> >@@ -715,6 +717,7 @@ > > icmp_param.data.icmph=*skb->h.icmph; > icmp_param.data.icmph.type=ICMP_ECHOREPLY; >+ > icmp_param.skb=skb; > icmp_param.offset=0; > icmp_param.data_len=skb->len; >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/ip_output.c linux-2.4.22-ppc-dev/net/ipv4/ip_output.c >--- linux-2.4.22-ppc-dev.orig/net/ipv4/ip_output.c 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/ipv4/ip_output.c 2003-09-14 14:07:43.000000000 +0200 >@@ -77,6 +77,7 @@ > #include <linux/netfilter_ipv4.h> > #include <linux/mroute.h> > #include <linux/netlink.h> >+#include <linux/grsecurity.h> > > /* > * Shall we try to damage output packets if routing dev changes? >@@ -514,7 +515,13 @@ > * Begin outputting the bytes. > */ > >- id = sk->protinfo.af_inet.id++; >+#ifdef CONFIG_GRKERNSEC_RANDID >+ if(grsec_enable_randid) { >+ id = htons(ip_randomid()); >+ sk->protinfo.af_inet.id = htons(ip_randomid()); >+ } else >+#endif >+ id = sk->protinfo.af_inet.id++; > > do { > char *data; >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/netfilter/Config.in linux-2.4.22-ppc-dev/net/ipv4/netfilter/Config.in >--- linux-2.4.22-ppc-dev.orig/net/ipv4/netfilter/Config.in 2003-09-14 14:03:23.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/ipv4/netfilter/Config.in 2003-09-14 14:07:43.000000000 +0200 >@@ -33,6 +33,7 @@ > dep_tristate ' LENGTH match support' CONFIG_IP_NF_MATCH_LENGTH $CONFIG_IP_NF_IPTABLES > dep_tristate ' TTL match support' CONFIG_IP_NF_MATCH_TTL $CONFIG_IP_NF_IPTABLES > dep_tristate ' tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $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 -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/netfilter/Makefile linux-2.4.22-ppc-dev/net/ipv4/netfilter/Makefile >--- linux-2.4.22-ppc-dev.orig/net/ipv4/netfilter/Makefile 2003-09-14 14:03:23.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/ipv4/netfilter/Makefile 2003-09-14 14:07:43.000000000 +0200 >@@ -86,6 +86,7 @@ > obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o > obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o > obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o >+obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o > > # targets > obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/netfilter/ipt_stealth.c linux-2.4.22-ppc-dev/net/ipv4/netfilter/ipt_stealth.c >--- linux-2.4.22-ppc-dev.orig/net/ipv4/netfilter/ipt_stealth.c 1970-01-01 01:00:00.000000000 +0100 >+++ linux-2.4.22-ppc-dev/net/ipv4/netfilter/ipt_stealth.c 2003-09-14 14:07:43.000000000 +0200 >@@ -0,0 +1,109 @@ >+/* Kernel module to add stealth support. >+ * >+ * Copyright (C) 2002 Brad Spengler <spender@grsecurity.net> >+ * >+ */ >+ >+#include <linux/kernel.h> >+#include <linux/module.h> >+#include <linux/skbuff.h> >+#include <linux/net.h> >+#include <linux/sched.h> >+#include <linux/inet.h> >+#include <linux/stddef.h> >+ >+#include <net/ip.h> >+#include <net/sock.h> >+#include <net/tcp.h> >+#include <net/udp.h> >+#include <net/route.h> >+#include <net/inet_common.h> >+ >+#include <linux/netfilter_ipv4/ip_tables.h> >+ >+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 -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/tcp_ipv4.c linux-2.4.22-ppc-dev/net/ipv4/tcp_ipv4.c >--- linux-2.4.22-ppc-dev.orig/net/ipv4/tcp_ipv4.c 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/ipv4/tcp_ipv4.c 2003-09-14 14:07:43.000000000 +0200 >@@ -67,6 +67,7 @@ > #include <linux/inet.h> > #include <linux/stddef.h> > #include <linux/ipsec.h> >+#include <linux/grsecurity.h> > > extern int sysctl_ip_dynaddr; > extern int sysctl_ip_default_ttl; >@@ -221,9 +222,18 @@ > > spin_lock(&tcp_portalloc_lock); > rover = tcp_port_rover; >- do { rover++; >- if ((rover < low) || (rover > high)) >- rover = low; >+ do { >+#ifdef CONFIG_GRKERNSEC_RANDSRC >+ if (grsec_enable_randsrc && (high > low)) { >+ rover = low + (get_random_long() % (high - low)); >+ } else >+#endif >+ { >+ rover++; >+ if ((rover < low) || (rover > high)) >+ rover = low; >+ } >+ > head = &tcp_bhash[tcp_bhashfn(rover)]; > spin_lock(&head->lock); > for (tb = head->chain; tb; tb = tb->next) >@@ -546,6 +556,11 @@ > > static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb) > { >+#ifdef CONFIG_GRKERNSEC_RANDISN >+ if (likely(grsec_enable_randisn)) >+ return ip_randomisn(); >+ else >+#endif > return secure_tcp_sequence_number(skb->nh.iph->daddr, > skb->nh.iph->saddr, > skb->h.th->dest, >@@ -681,9 +696,16 @@ > rover = tcp_port_rover; > > do { >- rover++; >- if ((rover < low) || (rover > high)) >- rover = low; >+#ifdef CONFIG_GRKERNSEC_RANDSRC >+ if(grsec_enable_randsrc && (high > low)) { >+ rover = low + (get_random_long() % (high - low)); >+ } else >+#endif >+ { >+ rover++; >+ if ((rover < low) || (rover > high)) >+ rover = low; >+ } > head = &tcp_bhash[tcp_bhashfn(rover)]; > spin_lock(&head->lock); > >@@ -844,11 +866,22 @@ > if (err) > goto failure; > >- if (!tp->write_seq) >+ if (!tp->write_seq) { >+#ifdef CONFIG_GRKERNSEC_RANDISN >+ if (likely(grsec_enable_randisn)) >+ tp->write_seq = ip_randomisn(); >+ else >+#endif > tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr, > sk->sport, usin->sin_port); >+ } > >- sk->protinfo.af_inet.id = tp->write_seq^jiffies; >+#ifdef CONFIG_GRKERNSEC_RANDID >+ if(grsec_enable_randid) >+ sk->protinfo.af_inet.id = htons(ip_randomid()); >+ else >+#endif >+ sk->protinfo.af_inet.id = tp->write_seq^jiffies; > > err = tcp_connect(sk); > if (err) >@@ -1570,7 +1603,13 @@ > newtp->ext_header_len = 0; > if (newsk->protinfo.af_inet.opt) > newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen; >- newsk->protinfo.af_inet.id = newtp->write_seq^jiffies; >+ >+#ifdef CONFIG_GRKERNSEC_RANDID >+ if(grsec_enable_randid) >+ newsk->protinfo.af_inet.id = htons(ip_randomid()); >+ else >+#endif >+ newsk->protinfo.af_inet.id = newtp->write_seq^jiffies; > > tcp_sync_mss(newsk, dst->pmtu); > newtp->advmss = dst->advmss; >diff -Naur linux-2.4.22-ppc-dev.orig/net/ipv4/udp.c linux-2.4.22-ppc-dev/net/ipv4/udp.c >--- linux-2.4.22-ppc-dev.orig/net/ipv4/udp.c 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/ipv4/udp.c 2003-09-14 14:07:43.000000000 +0200 >@@ -91,6 +91,7 @@ > #include <net/ipv6.h> > #include <net/protocol.h> > #include <linux/skbuff.h> >+#include <linux/grsecurity.h> > #include <net/sock.h> > #include <net/udp.h> > #include <net/icmp.h> >@@ -98,6 +99,11 @@ > #include <net/inet_common.h> > #include <net/checksum.h> > >+extern int gr_search_udp_recvmsg(const struct sock *sk, >+ const struct sk_buff *skb); >+extern int gr_search_udp_sendmsg(const struct sock *sk, >+ const struct sockaddr_in *addr); >+ > /* > * Snmp MIB for the UDP layer > */ >@@ -478,9 +484,16 @@ > ufh.uh.dest = usin->sin_port; > if (ufh.uh.dest == 0) > return -EINVAL; >+ >+ if (!gr_search_udp_sendmsg(sk, usin)) >+ return -EPERM; > } else { > if (sk->state != TCP_ESTABLISHED) > return -EDESTADDRREQ; >+ >+ if (!gr_search_udp_sendmsg(sk, NULL)) >+ return -EPERM; >+ > ufh.daddr = sk->daddr; > ufh.uh.dest = sk->dport; > /* Open fast path for connected socket. >@@ -488,6 +501,7 @@ > */ > connected = 1; > } >+ > ipc.addr = sk->saddr; > ufh.uh.source = sk->sport; > >@@ -659,6 +673,11 @@ > if (!skb) > goto out; > >+ if (!gr_search_udp_recvmsg(sk, skb)) { >+ err = -EPERM; >+ goto out_free; >+ } >+ > copied = skb->len - sizeof(struct udphdr); > if (copied > len) { > copied = len; >@@ -763,7 +782,13 @@ > sk->daddr = rt->rt_dst; > sk->dport = usin->sin_port; > sk->state = TCP_ESTABLISHED; >- sk->protinfo.af_inet.id = jiffies; >+ >+#ifdef CONFIG_GRKERNSEC_RANDID >+ if(grsec_enable_randid) >+ sk->protinfo.af_inet.id = htons(ip_randomid()); >+ else >+#endif >+ sk->protinfo.af_inet.id = jiffies; > > sk_dst_set(sk, &rt->u.dst); > return(0); >diff -Naur linux-2.4.22-ppc-dev.orig/net/netlink/af_netlink.c linux-2.4.22-ppc-dev/net/netlink/af_netlink.c >--- linux-2.4.22-ppc-dev.orig/net/netlink/af_netlink.c 2003-09-14 14:03:25.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/netlink/af_netlink.c 2003-09-14 14:07:43.000000000 +0200 >@@ -40,6 +40,7 @@ > #include <linux/proc_fs.h> > #include <linux/smp_lock.h> > #include <linux/notifier.h> >+#include <linux/grsecurity.h> > #include <net/sock.h> > #include <net/scm.h> > >@@ -625,7 +626,8 @@ > check them, when this message will be delivered > to corresponding kernel module. --ANK (980802) > */ >- NETLINK_CB(skb).eff_cap = current->cap_effective; >+ >+ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(); > > err = -EFAULT; > if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) { >diff -Naur linux-2.4.22-ppc-dev.orig/net/netsyms.c linux-2.4.22-ppc-dev/net/netsyms.c >--- linux-2.4.22-ppc-dev.orig/net/netsyms.c 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/netsyms.c 2003-09-14 14:07:43.000000000 +0200 >@@ -24,6 +24,7 @@ > #include <net/checksum.h> > #include <linux/etherdevice.h> > #include <net/route.h> >+#include <linux/grsecurity.h> > #ifdef CONFIG_HIPPI > #include <linux/hippidevice.h> > #endif >@@ -606,6 +607,49 @@ > > 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 >+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif); >+EXPORT_SYMBOL(udp_v4_lookup); >+#endif >+ >+#if defined(CONFIG_GRKERNSEC_RANDID) >+EXPORT_SYMBOL(ip_randomid); >+#endif >+#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC) >+EXPORT_SYMBOL(get_random_long); >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDISN >+EXPORT_SYMBOL(ip_randomisn); >+EXPORT_SYMBOL(grsec_enable_randisn); >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDID >+EXPORT_SYMBOL(grsec_enable_randid); >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDSRC >+EXPORT_SYMBOL(grsec_enable_randsrc); >+#endif >+#ifdef CONFIG_GRKERNSEC_RANDRPC >+EXPORT_SYMBOL(grsec_enable_randrpc); >+#endif >+ >+EXPORT_SYMBOL(gr_cap_rtnetlink); >+ >+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb); >+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr); >+ >+EXPORT_SYMBOL(gr_search_udp_recvmsg); >+EXPORT_SYMBOL(gr_search_udp_sendmsg); >+ >+#ifdef CONFIG_UNIX_MODULE >+EXPORT_SYMBOL(gr_acl_handle_unix); >+EXPORT_SYMBOL(gr_acl_handle_mknod); >+EXPORT_SYMBOL(gr_handle_chroot_unix); >+EXPORT_SYMBOL(gr_handle_create); >+#endif >+ > #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) > #include <net/iw_handler.h> > EXPORT_SYMBOL(wireless_send_event); >diff -Naur linux-2.4.22-ppc-dev.orig/net/socket.c linux-2.4.22-ppc-dev/net/socket.c >--- linux-2.4.22-ppc-dev.orig/net/socket.c 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/socket.c 2003-09-14 14:07:43.000000000 +0200 >@@ -85,6 +85,18 @@ > #include <net/scm.h> > #include <linux/netfilter.h> > >+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); >+extern int gr_search_connect(const struct socket * sock, >+ const struct sockaddr_in * addr); >+extern int gr_search_bind(const struct socket * sock, >+ const struct sockaddr_in * addr); >+extern int gr_search_socket(const int domain, const int type, >+ const int protocol); >+ > 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,16 @@ > int retval; > struct socket *sock; > >+ if(!gr_search_socket(family, type, protocol)) { >+ retval = -EACCES; >+ goto out; >+ } >+ >+ if (gr_handle_sock_all(family, type, protocol)) { >+ retval = -EACCES; >+ goto out; >+ } >+ > retval = sock_create(family, type, protocol, &sock); > if (retval < 0) > goto out; >@@ -998,12 +1034,26 @@ > { > 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) { >+ sck = (struct sockaddr *) address; >+ >+ if(!gr_search_bind(sock, (struct sockaddr_in *) sck)) { >+ sockfd_put(sock); >+ return -EACCES; >+ } >+ >+ if (gr_handle_sock_server(sck)) { >+ sockfd_put(sock); >+ return -EACCES; >+ } >+ > err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen); >+ } > sockfd_put(sock); > } > return err; >@@ -1079,6 +1129,8 @@ > if ((err = sock_map_fd(newsock)) < 0) > goto out_release; > >+ gr_attach_curr_ip(newsock->sk); >+ > 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,24 @@ > err = move_addr_to_kernel(uservaddr, addrlen, address); > if (err < 0) > goto out_put; >+ >+ sck = (struct sockaddr *) address; >+ >+ if (!gr_search_connect(sock, (struct sockaddr_in *) sck)) { >+ err = -EACCES; >+ goto out_put; >+ } >+ >+ if (gr_handle_sock_client(sck)) { >+ err = -EACCES; >+ goto out_put; >+ } >+ >+#ifdef CONFIG_GRKERNSEC >+ 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 -Naur linux-2.4.22-ppc-dev.orig/net/sunrpc/xprt.c linux-2.4.22-ppc-dev/net/sunrpc/xprt.c >--- linux-2.4.22-ppc-dev.orig/net/sunrpc/xprt.c 2003-09-14 14:03:25.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/sunrpc/xprt.c 2003-09-14 14:07:43.000000000 +0200 >@@ -59,6 +59,7 @@ > #include <linux/unistd.h> > #include <linux/sunrpc/clnt.h> > #include <linux/file.h> >+#include <linux/grsecurity.h> > > #include <net/sock.h> > #include <net/checksum.h> >@@ -1290,6 +1291,12 @@ > } > ret = xid++; > spin_unlock(&xid_lock); >+ >+#ifdef CONFIG_GRKERNSEC_RANDRPC >+ if (grsec_enable_randrpc) >+ ret = (u32) get_random_long(); >+#endif >+ > return ret; > } > >diff -Naur linux-2.4.22-ppc-dev.orig/net/unix/af_unix.c linux-2.4.22-ppc-dev/net/unix/af_unix.c >--- linux-2.4.22-ppc-dev.orig/net/unix/af_unix.c 2003-09-14 14:03:22.000000000 +0200 >+++ linux-2.4.22-ppc-dev/net/unix/af_unix.c 2003-09-14 14:07:43.000000000 +0200 >@@ -109,6 +109,7 @@ > #include <linux/poll.h> > #include <linux/smp_lock.h> > #include <linux/rtnetlink.h> >+#include <linux/grsecurity.h> > > #include <asm/checksum.h> > >@@ -599,6 +600,11 @@ > if (err) > goto put_fail; > >+ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) { >+ err = -EACCES; >+ goto put_fail; >+ } >+ > err = -ECONNREFUSED; > if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) > goto put_fail; >@@ -622,6 +628,13 @@ > if (u) { > struct dentry *dentry; > dentry = u->protinfo.af_unix.dentry; >+ >+ if (!gr_handle_chroot_unix(u->peercred.pid)) { >+ err = -EPERM; >+ sock_put(u); >+ goto fail; >+ } >+ > if (dentry) > UPDATE_ATIME(dentry->d_inode); > } else >@@ -720,9 +733,19 @@ > * All right, let's create it. > */ > mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask); >+ >+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) { >+ err = -EACCES; >+ goto out_mknod_dput; >+ } >+ > err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0); >+ > if (err) > goto out_mknod_dput; >+ >+ gr_handle_create(dentry, nd.mnt); >+ > up(&nd.dentry->d_inode->i_sem); > dput(nd.dentry); > nd.dentry = dentry; >@@ -740,6 +763,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;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 35819
:
22205
|
22206
|
22207
|
22208
|
22209
| 22210 |
22211
|
22212
|
22213
|
22214
|
22215