]> git.pld-linux.org Git - packages/kernel.git/blame - grsecurity-nopax-2.0-rc3-2.4.22.patch
- obsolete
[packages/kernel.git] / grsecurity-nopax-2.0-rc3-2.4.22.patch
CommitLineData
ada7ca3f
JR
1diff -urN linux-2.4.22/Documentation/Configure.help linux-2.4.22/Documentation/Configure.help
2--- linux-2.4.22/Documentation/Configure.help 2003-09-01 22:19:45.000000000 -0400
3+++ linux-2.4.22/Documentation/Configure.help 2003-09-02 19:29:41.000000000 -0400
4@@ -2725,6 +2725,20 @@
5 If you want to compile it as a module, say M here and read
6 Documentation/modules.txt. If unsure, say `N'.
7
8+stealth networking support
9+CONFIG_IP_NF_MATCH_STEALTH
10+ Enabling this option will drop all syn packets coming to unserved tcp
11+ ports as well as all packets coming to unserved udp ports. If you
12+ are using your system to route any type of packets (ie. via NAT)
13+ you should put this module at the end of your ruleset, since it will
14+ drop packets that aren't going to ports that are listening on your
15+ machine itself, it doesn't take into account that the packet might be
16+ destined for someone on your internal network if you're using NAT for
17+ instance.
18+
19+ If you want to compile it as a module, say M here and read
20+ Documentation/modules.txt. If unsure, say `N'.
21+
22 MAC address match support
23 CONFIG_IP_NF_MATCH_MAC
24 MAC matching allows you to match packets based on the source
25@@ -22263,6 +22277,609 @@
26
27 "Area6" will work for most boards. For ADX, select "Area5".
28
29+Grsecurity
30+CONFIG_GRKERNSEC
31+ If you say Y here, you will be able to configure many features that
32+ will enhance the security of your system. It is highly recommended
33+ that you say Y here and read through the help for each option so
34+ you fully understand the features and can evaluate their usefulness
35+ for your machine.
36+
37+Additional security levels
38+CONFIG_GRKERNSEC_LOW
39+
40+ Low additional security
41+ -----------------------------------------------------------------------
42+ If you choose this option, several of the grsecurity options will
43+ be enabled that will give you greater protection against a number
44+ of attacks, while assuring that none of your software will have any
45+ conflicts with the additional security measures. If you run a lot of
46+ unusual software, or you are having problems with the higher security
47+ levels, you should say Y here. With this option, the following features
48+ are enabled:
49+
50+ linking restrictions
51+ fifo restrictions
52+ random pids
53+ enforcing nproc on execve()
54+ restricted dmesg
55+ random ip ids
56+ enforced chdir("/") on chroot
57+
58+ Medium additional security
59+ -----------------------------------------------------------------------
60+ If you say Y here, several features in addition to those included in the
61+ low additional security level will be enabled. These features provide
62+ even more security to your system, though in rare cases they may
63+ be incompatible with very old or poorly written software. If you
64+ enable this option, make sure that your auth service (identd) is
65+ running as gid 10 (usually group wheel). With this option the following
66+ features (in addition to those provided in the low additional security
67+ level) will be enabled:
68+
69+ random tcp source ports
70+ altered ping ids
71+ failed fork logging
72+ time change logging
73+ signal logging
74+ deny mounts in chroot
75+ deny double chrooting
76+ deny sysctl writes in chroot
77+ deny mknod in chroot
78+ deny access to abstract AF_UNIX sockets out of chroot
79+ deny pivot_root in chroot
80+ denied writes of /dev/kmem, /dev/mem, and /dev/port
81+ /proc restrictions with special gid set to 10 (usually wheel)
82+ address space layout randomization
83+
84+ High additional security
85+ ----------------------------------------------------------------------
86+ If you say Y here, many of the features of grsecurity will be enabled,
87+ that will protect you against many kinds of attacks against
88+ your system. The heightened security comes at a cost of an
89+ increased chance of incompatibilities with rare software on your
90+ machine. It is highly recommended that you view
91+ <http://grsecurity.net/features.htm> and read about each option.
92+ Also remember that since the /proc restrictions are
93+ enabled, you must run your identd as group wheel (gid 10).
94+ This security level enables the following features in addition to those
95+ listed in the low and medium security levels:
96+
97+ additional /proc restrictions
98+ chmod restrictions in chroot
99+ no signals, ptrace, or viewing processes outside of chroot
100+ capability restrictions in chroot
101+ deny fchdir out of chroot
102+ priority restrictions in chroot
103+ mprotect restrictions
104+ removal of /proc/<pid>/[maps|mem]
105+ kernel stack randomization
106+ mount/unmount/remount logging
107+ kernel symbol hiding
108+
109+Customized additional security
110+CONFIG_GRKERNSEC_CUSTOM
111+ If you say Y here, you will be able to configure every grsecurity
112+ option, which allows you to enable many more features that aren't
113+ covered in the basic security levels. These additional features include
114+ TPE, socket restrictions, and the sysctl system for grsecurity. It is
115+ advised that you read through the help for each option to determine its
116+ usefulness in your situation.
117+
118+Deny writing to /dev/kmem, /dev/mem, and /dev/port
119+CONFIG_GRKERNSEC_KMEM
120+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
121+ be written to via mmap or otherwise to modify the running kernel.
122+ /dev/port will also not be allowed to be opened. If you have module
123+ support disabled, enabling this will close up four ways that are
124+ currently used to insert malicious code into the running kernel.
125+ Even with all these features enabled, we still highly recommend that
126+ you use the ACL system, as it is still possible for an attacker to
127+ modify the running kernel through privileged I/O granted by ioperm/iopl.
128+ If you are not using XFree86, you may be able to stop this additional
129+ case by enabling the 'Disable privileged I/O' option. Though nothing
130+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
131+ but only to video memory, which is the only writing we allow in this
132+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
133+ not be allowed to mprotect it with PROT_WRITE later.
134+ Enabling this feature could make certain apps like VMWare stop working,
135+ as they need to write to other locations in /dev/mem.
136+ It is highly recommended that you say Y here if you meet all the
137+ conditions above.
138+
139+Disable privileged I/O
140+CONFIG_GRKERNSEC_IO
141+ If you say Y here, all ioperm and iopl calls will return an error.
142+ Ioperm and iopl can be used to modify the running kernel.
143+ Unfortunately, some programs need this access to operate properly,
144+ the most notable of which are XFree86 and hwclock. hwclock can be
145+ remedied by having RTC support in the kernel, so CONFIG_RTC is
146+ enabled if this option is enabled, to ensure that hwclock operates
147+ correctly. XFree86 still will not operate correctly with this option
148+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
149+ and you still want to protect your kernel against modification,
150+ use the ACL system.
151+
152+Hide kernel symbols
153+CONFIG_GRKERNSEC_HIDESYM
154+ If you say Y here, getting information on loaded modules, and
155+ displaying all kernel symbols through a syscall will be restricted
156+ to users with CAP_SYS_MODULE. This option is only effective
157+ provided the following conditions are met:
158+ 1) The kernel using grsecurity is not precompiled by some distribution
159+ 2) You are using the ACL system and hiding other files such as your
160+ kernel image and System.map
161+ 3) You have the additional /proc restrictions enabled, which removes
162+ /proc/kcore
163+ If the above conditions are met, this option will aid to provide a
164+ useful protection against local and remote kernel exploitation of
165+ overflows and arbitrary read/write vulnerabilities.
166+
167+/proc/<pid>/ipaddr support
168+CONFIG_GRKERNSEC_PROC_IPADDR
169+ If you say Y here, a new entry will be added to each /proc/<pid>
170+ directory that contains the IP address of the person using the task.
171+ The IP is carried across local TCP and AF_UNIX stream sockets.
172+ This information can be useful for IDS/IPSes to perform remote response
173+ to a local attack. The entry is readable by only the owner of the
174+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
175+ the RBAC system), and thus does not create privacy concerns.
176+
177+Proc Restrictions
178+CONFIG_GRKERNSEC_PROC
179+ If you say Y here, the permissions of the /proc filesystem
180+ will be altered to enhance system security and privacy. Depending
181+ upon the options you choose, you can either restrict users to see
182+ only the processes they themselves run, or choose a group that can
183+ view all processes and files normally restricted to root if you choose
184+ the "restrict to user only" option. NOTE: If you're running identd as
185+ a non-root user, you will have to run it as the group you specify here.
186+
187+Restrict /proc to user only
188+CONFIG_GRKERNSEC_PROC_USER
189+ If you say Y here, non-root users will only be able to view their own
190+ processes, and restricts them from viewing network-related information,
191+ and viewing kernel symbol and module information.
192+
193+Restrict /proc to user and group
194+CONFIG_GRKERNSEC_PROC_USERGROUP
195+ If you say Y here, you will be able to select a group that will be
196+ able to view all processes, network-related information, and
197+ kernel and symbol information. This option is useful if you want
198+ to run identd as a non-root user.
199+
200+Additional proc restrictions
201+CONFIG_GRKERNSEC_PROC_ADD
202+ If you say Y here, additional restrictions will be placed on
203+ /proc that keep normal users from viewing cpu and device information.
204+
205+Dmesg(8) Restriction
206+CONFIG_GRKERNSEC_DMESG
207+ If you say Y here, non-root users will not be able to use dmesg(8)
208+ to view up to the last 4kb of messages in the kernel's log buffer.
209+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
210+ created.
211+
212+Linking restrictions
213+CONFIG_GRKERNSEC_LINK
214+ If you say Y here, /tmp race exploits will be prevented, since users
215+ will no longer be able to follow symlinks owned by other users in
216+ world-writable +t directories (i.e. /tmp), unless the owner of the
217+ symlink is the owner of the directory. users will also not be
218+ able to hardlink to files they do not own. If the sysctl option is
219+ enabled, a sysctl option with name "linking_restrictions" is created.
220+
221+FIFO restrictions
222+CONFIG_GRKERNSEC_FIFO
223+ If you say Y here, users will not be able to write to FIFOs they don't
224+ own in world-writable +t directories (i.e. /tmp), unless the owner of
225+ the FIFO is the same owner of the directory it's held in. If the sysctl
226+ option is enabled, a sysctl option with name "fifo_restrictions" is
227+ created.
228+
229+Enforce RLIMIT_NPROC on execs
230+CONFIG_GRKERNSEC_EXECVE
231+ If you say Y here, users with a resource limit on processes will
232+ have the value checked during execve() calls. The current system
233+ only checks the system limit during fork() calls. If the sysctl option
234+ is enabled, a sysctl option with name "execve_limiting" is created.
235+
236+Single group for auditing
237+CONFIG_GRKERNSEC_AUDIT_GROUP
238+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
239+ will only operate on a group you specify. This option is recommended
240+ if you only want to watch certain users instead of having a large
241+ amount of logs from the entire system. If the sysctl option is enabled,
242+ a sysctl option with name "audit_group" is created.
243+
244+GID for auditing
245+CONFIG_GRKERNSEC_AUDIT_GID
246+ Here you can choose the GID that will be the target of kernel auditing.
247+ Remember to add the users you want to log to the GID specified here.
248+ If the sysctl option is enabled, whatever you choose here won't matter.
249+ You'll have to specify the GID in your bootup script by echoing the GID
250+ to the proper /proc entry. View the help on the sysctl option for more
251+ information. If the sysctl option is enabled, a sysctl option with name
252+ "audit_gid" is created.
253+
254+Chdir logging
255+CONFIG_GRKERNSEC_AUDIT_CHDIR
256+ If you say Y here, all chdir() calls will be logged. If the sysctl
257+ option is enabled, a sysctl option with name "audit_chdir" is created.
258+
259+(Un)Mount logging
260+CONFIG_GRKERNSEC_AUDIT_MOUNT
261+ If you say Y here, all mounts and unmounts will be logged. If the
262+ sysctl option is enabled, a sysctl option with name "audit_mount" is
263+ created.
264+
265+IPC logging
266+CONFIG_GRKERNSEC_AUDIT_IPC
267+ If you say Y here, creation and removal of message queues, semaphores,
268+ and shared memory will be logged. If the sysctl option is enabled, a
269+ sysctl option with name "audit_ipc" is created.
270+
271+Exec logging
272+CONFIG_GRKERNSEC_EXECLOG
273+ If you say Y here, all execve() calls will be logged (since the
274+ other exec*() calls are frontends to execve(), all execution
275+ will be logged). Useful for shell-servers that like to keep track
276+ of their users. If the sysctl option is enabled, a sysctl option with
277+ name "exec_logging" is created.
278+ WARNING: This option when enabled will produce a LOT of logs, especially
279+ on an active system.
280+
281+Resource logging
282+CONFIG_GRKERNSEC_RESLOG
283+ If you say Y here, all attempts to overstep resource limits will
284+ be logged with the resource name, the requested size, and the current
285+ limit. It is highly recommended that you say Y here.
286+
287+Signal logging
288+CONFIG_GRKERNSEC_SIGNAL
289+ If you say Y here, certain important signals will be logged, such as
290+ SIGSEGV, which will as a result inform you of when a error in a program
291+ occurred, which in some cases could mean a possible exploit attempt.
292+ If the sysctl option is enabled, a sysctl option with name
293+ "signal_logging" is created.
294+
295+Fork failure logging
296+CONFIG_GRKERNSEC_FORKFAIL
297+ If you say Y here, all failed fork() attempts will be logged.
298+ This could suggest a fork bomb, or someone attempting to overstep
299+ their process limit. If the sysctl option is enabled, a sysctl option
300+ with name "forkfail_logging" is created.
301+
302+Time change logging
303+CONFIG_GRKERNSEC_TIME
304+ If you say Y here, any changes of the system clock will be logged.
305+ If the sysctl option is enabled, a sysctl option with name
306+ "timechange_logging" is created.
307+
308+Chroot jail restrictions
309+CONFIG_GRKERNSEC_CHROOT
310+ If you say Y here, you will be able to choose several options that will
311+ make breaking out of a chrooted jail much more difficult. If you
312+ encounter no software incompatibilities with the following options, it
313+ is recommended that you enable each one.
314+
315+Deny access to abstract AF_UNIX sockets out of chroot
316+CONFIG_GRKERNSEC_CHROOT_UNIX
317+ If you say Y here, processes inside a chroot will not be able to
318+ connect to abstract (meaning not belonging to a filesystem) Unix
319+ domain sockets that were bound outside of a chroot. It is recommended
320+ that you say Y here. If the sysctl option is enabled, a sysctl option
321+ with name "chroot_deny_unix" is created.
322+
323+Deny shmat() out of chroot
324+CONFIG_GRKERNSEC_CHROOT_SHMAT
325+ If you say Y here, processes inside a chroot will not be able to attach
326+ to shared memory segments that were created outside of the chroot jail.
327+ It is recommended that you say Y here. If the sysctl option is enabled,
328+ a sysctl option with name "chroot_deny_shmat" is created.
329+
330+Protect outside processes
331+CONFIG_GRKERNSEC_CHROOT_FINDTASK
332+ If you say Y here, processes inside a chroot will not be able to
333+ kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
334+ getsid, or view any process outside of the chroot. If the sysctl
335+ option is enabled, a sysctl option with name "chroot_findtask" is
336+ created.
337+
338+Deny mounts in chroot
339+CONFIG_GRKERNSEC_CHROOT_MOUNT
340+ If you say Y here, processes inside a chroot will not be able to
341+ mount or remount filesystems. If the sysctl option is enabled, a
342+ sysctl option with name "chroot_deny_mount" is created.
343+
344+Deny pivot_root in chroot
345+CONFIG_GRKERNSEC_CHROOT_PIVOT
346+ If you say Y here, processes inside a chroot will not be able to use
347+ a function called pivot_root() that was introduced in Linux 2.3.41. It
348+ works similar to chroot in that it changes the root filesystem. This
349+ function could be misused in a chrooted process to attempt to break out
350+ of the chroot, and therefore should not be allowed. If the sysctl
351+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
352+ created.
353+
354+Deny double-chroots
355+CONFIG_GRKERNSEC_CHROOT_DOUBLE
356+ If you say Y here, processes inside a chroot will not be able to chroot
357+ again. This is a widely used method of breaking out of a chroot jail
358+ and should not be allowed. If the sysctl option is enabled, a sysctl
359+ option with name "chroot_deny_chroot" is created.
360+
361+Deny fchdir outside of chroot
362+CONFIG_GRKERNSEC_CHROOT_FCHDIR
363+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
364+ to a file descriptor of the chrooting process that points to a directory
365+ outside the filesystem will be stopped. If the sysctl option
366+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
367+
368+Enforce chdir("/") on all chroots
369+CONFIG_GRKERNSEC_CHROOT_CHDIR
370+ If you say Y here, the current working directory of all newly-chrooted
371+ applications will be set to the the root directory of the chroot.
372+ The man page on chroot(2) states:
373+ Note that this call does not change the current working
374+ directory, so that `.' can be outside the tree rooted at
375+ `/'. In particular, the super-user can escape from a
376+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
377+
378+ It is recommended that you say Y here, since it's not known to break
379+ any software. If the sysctl option is enabled, a sysctl option with
380+ name "chroot_enforce_chdir" is created.
381+
382+Deny (f)chmod +s in chroot
383+CONFIG_GRKERNSEC_CHROOT_CHMOD
384+ If you say Y here, processes inside a chroot will not be able to chmod
385+ or fchmod files to make them have suid or sgid bits. This protects
386+ against another published method of breaking a chroot. If the sysctl
387+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
388+ created.
389+
390+Deny mknod in chroot
391+CONFIG_GRKERNSEC_CHROOT_MKNOD
392+ If you say Y here, processes inside a chroot will not be allowed to
393+ mknod. The problem with using mknod inside a chroot is that it
394+ would allow an attacker to create a device entry that is the same
395+ as one on the physical root of your system, which could range from
396+ anything from the console device to a device for your harddrive (which
397+ they could then use to wipe the drive or steal data). It is recommended
398+ that you say Y here, unless you run into software incompatibilities.
399+ If the sysctl option is enabled, a sysctl option with name
400+ "chroot_deny_mknod" is created.
401+
402+Restrict priority changes in chroot
403+CONFIG_GRKERNSEC_CHROOT_NICE
404+ If you say Y here, processes inside a chroot will not be able to raise
405+ the priority of processes in the chroot, or alter the priority of
406+ processes outside the chroot. This provides more security than simply
407+ removing CAP_SYS_NICE from the process' capability set. If the
408+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
409+ is created.
410+
411+Log all execs within chroot
412+CONFIG_GRKERNSEC_CHROOT_EXECLOG
413+ If you say Y here, all executions inside a chroot jail will be logged
414+ to syslog. This can cause a large amount of logs if certain
415+ applications (eg. djb's daemontools) are installed on the system, and
416+ is therefore left as an option. If the sysctl option is enabled, a
417+ sysctl option with name "chroot_execlog" is created.
418+
419+Deny sysctl writes in chroot
420+CONFIG_GRKERNSEC_CHROOT_SYSCTL
421+ If you say Y here, an attacker in a chroot will not be able to
422+ write to sysctl entries, either by sysctl(2) or through a /proc
423+ interface. It is strongly recommended that you say Y here. If the
424+ sysctl option is enabled, a sysctl option with name
425+ "chroot_deny_sysctl" is created.
426+
427+Chroot jail capability restrictions
428+CONFIG_GRKERNSEC_CHROOT_CAPS
429+ If you say Y here, the capabilities on all root processes within a
430+ chroot jail will be lowered to stop module insertion, raw i/o,
431+ system and net admin tasks, rebooting the system, modifying immutable
432+ files, modifying IPC owned by another, and changing the system time.
433+ This is left an option because it can break some apps. Disable this
434+ if your chrooted apps are having problems performing those kinds of
435+ tasks. If the sysctl option is enabled, a sysctl option with
436+ name "chroot_caps" is created.
437+
438+Trusted path execution
439+CONFIG_GRKERNSEC_TPE
440+ If you say Y here, you will be able to choose a gid to add to the
441+ supplementary groups of users you want to mark as "untrusted."
442+ These users will not be able to execute any files that are not in
443+ root-owned directories writable only by root. If the sysctl option
444+ is enabled, a sysctl option with name "tpe" is created.
445+
446+Group for trusted path execution
447+CONFIG_GRKERNSEC_TPE_GID
448+ Here you can choose the GID to enable trusted path protection for.
449+ Remember to add the users you want protection enabled for to the GID
450+ specified here. If the sysctl option is enabled, whatever you choose
451+ here won't matter. You'll have to specify the GID in your bootup
452+ script by echoing the GID to the proper /proc entry. View the help
453+ on the sysctl option for more information. If the sysctl option is
454+ enabled, a sysctl option with name "tpe_gid" is created.
455+
456+Partially restrict non-root users
457+CONFIG_GRKERNSEC_TPE_ALL
458+ If you say Y here, All non-root users other than the ones in the
459+ group specified in the main TPE option will only be allowed to
460+ execute files in directories they own that are not group or
461+ world-writable, or in directories owned by root and writable only by
462+ root. If the sysctl option is enabled, a sysctl option with name
463+ "tpe_restrict_all" is created.
464+
465+Randomized PIDs
466+CONFIG_GRKERNSEC_RANDPID
467+ If you say Y here, all PIDs created on the system will be
468+ pseudo-randomly generated. This is extremely effective along
469+ with the /proc restrictions to disallow an attacker from guessing
470+ pids of daemons, etc. PIDs are also used in some cases as part
471+ of a naming system for temporary files, so this option would keep
472+ those filenames from being predicted as well. We also use code
473+ to make sure that PID numbers aren't reused too soon. If the sysctl
474+ option is enabled, a sysctl option with name "rand_pids" is created.
475+
476+Larger entropy pools
477+CONFIG_GRKERNSEC_RANDNET
478+ If you say Y here, the entropy pools used for many features of Linux
479+ and grsecurity will be doubled in size. Since several grsecurity
480+ features use additional randomness, it is recommended that you say Y
481+ here. Saying Y here has a similar effect as modifying
482+ /proc/sys/kernel/random/poolsize.
483+
484+Truly random TCP ISN selection
485+CONFIG_GRKERNSEC_RANDISN
486+ If you say Y here, Linux's default selection of TCP Initial Sequence
487+ Numbers (ISNs) will be replaced with that of OpenBSD. Linux uses
488+ an MD4 hash based on the connection plus a time value to create the
489+ ISN, while OpenBSD's selection is random. If the sysctl option is
490+ enabled, a sysctl option with name "rand_isns" is created.
491+
492+Randomized IP IDs
493+CONFIG_GRKERNSEC_RANDID
494+ If you say Y here, all the id field on all outgoing packets
495+ will be randomized. This hinders os fingerprinters and
496+ keeps your machine from being used as a bounce for an untraceable
497+ portscan. Ids are used for fragmented packets, fragments belonging
498+ to the same packet have the same id. By default linux only
499+ increments the id value on each packet sent to an individual host.
500+ We use a port of the OpenBSD random ip id code to achieve the
501+ randomness, while keeping the possibility of id duplicates to
502+ near none. If the sysctl option is enabled, a sysctl option with name
503+ "rand_ip_ids" is created.
504+
505+Randomized TCP source ports
506+CONFIG_GRKERNSEC_RANDSRC
507+ If you say Y here, situations where a source port is generated on the
508+ fly for the TCP protocol (ie. with connect() ) will be altered so that
509+ the source port is generated at random, instead of a simple incrementing
510+ algorithm. If the sysctl option is enabled, a sysctl option with name
511+ "rand_tcp_src_ports" is created.
512+
513+Randomized RPC XIDs
514+CONFIG_GRKERNSEC_RANDRPC
515+ If you say Y here, the method of determining XIDs for RPC requests will
516+ be randomized, instead of using linux's default behavior of simply
517+ incrementing the XID. If you want your RPC connections to be more
518+ secure, say Y here. If the sysctl option is enabled, a sysctl option
519+ with name "rand_rpc" is created.
520+
521+Socket restrictions
522+CONFIG_GRKERNSEC_SOCKET
523+ If you say Y here, you will be able to choose from several options.
524+ If you assign a GID on your system and add it to the supplementary
525+ groups of users you want to restrict socket access to, this patch
526+ will perform up to three things, based on the option(s) you choose.
527+
528+Deny all socket access
529+CONFIG_GRKERNSEC_SOCKET_ALL
530+ If you say Y here, you will be able to choose a GID of whose users will
531+ be unable to connect to other hosts from your machine or run server
532+ applications from your machine. If the sysctl option is enabled, a
533+ sysctl option with name "socket_all" is created.
534+
535+Group for disabled socket access
536+CONFIG_GRKERNSEC_SOCKET_ALL_GID
537+ Here you can choose the GID to disable socket access for. Remember to
538+ add the users you want socket access disabled for to the GID
539+ specified here. If the sysctl option is enabled, whatever you choose
540+ here won't matter. You'll have to specify the GID in your bootup
541+ script by echoing the GID to the proper /proc entry. View the help
542+ on the sysctl option for more information. If the sysctl option is
543+ enabled, a sysctl option with name "socket_all_gid" is created.
544+
545+Deny all client socket access
546+CONFIG_GRKERNSEC_SOCKET_CLIENT
547+ If you say Y here, you will be able to choose a GID of whose users will
548+ be unable to connect to other hosts from your machine, but will be
549+ able to run servers. If this option is enabled, all users in the group
550+ you specify will have to use passive mode when initiating ftp transfers
551+ from the shell on your machine. If the sysctl option is enabled, a
552+ sysctl option with name "socket_client" is created.
553+
554+Group for disabled client socket access
555+CONFIG_GRKERNSEC_SOCKET_CLIENT_GID
556+ Here you can choose the GID to disable client socket access for.
557+ Remember to add the users you want client socket access disabled for to
558+ the GID specified here. If the sysctl option is enabled, whatever you
559+ choose here won't matter. You'll have to specify the GID in your bootup
560+ script by echoing the GID to the proper /proc entry. View the help
561+ on the sysctl option for more information. If the sysctl option is
562+ enabled, a sysctl option with name "socket_client_gid" is created.
563+
564+Deny all server socket access
565+CONFIG_GRKERNSEC_SOCKET_SERVER
566+ If you say Y here, you will be able to choose a GID of whose users will
567+ be unable to run server applications from your machine. If the sysctl
568+ option is enabled, a sysctl option with name "socket_server" is created.
569+
570+Group for disabled server socket access
571+CONFIG_GRKERNSEC_SOCKET_SERVER_GID
572+ Here you can choose the GID to disable server socket access for.
573+ Remember to add the users you want server socket access disabled for to
574+ the GID specified here. If the sysctl option is enabled, whatever you
575+ choose here won't matter. You'll have to specify the GID in your bootup
576+ script by echoing the GID to the proper /proc entry. View the help
577+ on the sysctl option for more information. If the sysctl option is
578+ enabled, a sysctl option with name "socket_server_gid" is created.
579+
580+Sysctl support
581+CONFIG_GRKERNSEC_SYSCTL
582+ If you say Y here, you will be able to change the options that
583+ grsecurity runs with at bootup, without having to recompile your
584+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
585+ to enable (1) or disable (0) various features. All the sysctl entries
586+ are mutable until the "grsec_lock" entry is set to a non-zero value.
587+ All features are disabled by default. Please note that this option could
588+ reduce the effectiveness of the added security of this patch if an ACL
589+ system is not put in place. Your init scripts should be read-only, and
590+ root should not have access to adding modules or performing raw i/o
591+ operations. All options should be set at startup, and the grsec_lock
592+ entry should be set to a non-zero value after all the options are set.
593+ *THIS IS EXTREMELY IMPORTANT*
594+
595+Number of burst messages
596+CONFIG_GRKERNSEC_FLOODBURST
597+ This option allows you to choose the maximum number of messages allowed
598+ within the flood time interval you chose in a separate option. The
599+ default should be suitable for most people, however if you find that
600+ many of your logs are being interpreted as flooding, you may want to
601+ raise this value.
602+
603+Seconds in between log messages
604+CONFIG_GRKERNSEC_FLOODTIME
605+ This option allows you to enforce the number of seconds between
606+ grsecurity log messages. The default should be suitable for most
607+ people, however, if you choose to change it, choose a value small enough
608+ to allow informative logs to be produced, but large enough to
609+ prevent flooding.
610+
611+Hide kernel processes
612+CONFIG_GRKERNSEC_ACL_HIDEKERN
613+ If you say Y here, when the ACL system is enabled via gradm -E,
614+ an additional ACL will be passed to the kernel that hides all kernel
615+ processes. These processes will only be viewable by the authenticated
616+ admin, or processes that have viewing access set.
617+
618+Maximum tries before password lockout
619+CONFIG_GRKERNSEC_ACL_MAXTRIES
620+ This option enforces the maximum number of times a user can attempt
621+ to authorize themselves with the grsecurity ACL system before being
622+ denied the ability to attempt authorization again for a specified time.
623+ The lower the number, the harder it will be to brute-force a password.
624+
625+Time to wait after max password tries, in seconds
626+CONFIG_GRKERNSEC_ACL_TIMEOUT
627+ This option specifies the time the user must wait after attempting to
628+ authorize to the ACL system with the maximum number of invalid
629+ passwords. The higher the number, the harder it will be to brute-force
630+ a password.
631+
632 Disable data cache
633 CONFIG_DCACHE_DISABLE
634 This option allows you to run the kernel with data cache disabled.
635diff -urN linux-2.4.22/Makefile linux-2.4.22/Makefile
636--- linux-2.4.22/Makefile 2003-09-01 22:19:00.000000000 -0400
637+++ linux-2.4.22/Makefile 2003-09-02 19:29:41.000000000 -0400
638@@ -1,7 +1,7 @@
639 VERSION = 2
640 PATCHLEVEL = 4
641 SUBLEVEL = 22
642-EXTRAVERSION =
643+EXTRAVERSION = -grsec
644
645 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
646
647@@ -126,9 +126,10 @@
648
649 CORE_FILES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
650 NETWORKS =net/network.o
651+GRSECURITY =grsecurity/grsec.o
652
653 LIBS =$(TOPDIR)/lib/lib.a
654-SUBDIRS =kernel drivers mm fs net ipc lib crypto
655+SUBDIRS =kernel drivers mm fs net ipc lib crypto grsecurity
656
657 DRIVERS-n :=
658 DRIVERS-y :=
659@@ -270,7 +271,7 @@
660
661 export CPPFLAGS CFLAGS CFLAGS_KERNEL AFLAGS AFLAGS_KERNEL
662
663-export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
664+export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS GRSECURITY
665
666 .S.s:
667 $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
668@@ -289,6 +290,7 @@
669 $(CORE_FILES) \
670 $(DRIVERS) \
671 $(NETWORKS) \
672+ $(GRSECURITY) \
673 $(LIBS) \
674 --end-group \
675 -o vmlinux
676diff -urN linux-2.4.22/arch/alpha/config.in linux-2.4.22/arch/alpha/config.in
677--- linux-2.4.22/arch/alpha/config.in 2003-09-01 22:19:33.000000000 -0400
678+++ linux-2.4.22/arch/alpha/config.in 2003-09-02 19:29:41.000000000 -0400
679@@ -457,3 +457,12 @@
680
681 source crypto/Config.in
682 source lib/Config.in
683+
684+mainmenu_option next_comment
685+comment 'Grsecurity'
686+bool 'Grsecurity' CONFIG_GRKERNSEC
687+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
688+ source grsecurity/Config.in
689+fi
690+endmenu
691+
692diff -urN linux-2.4.22/arch/alpha/kernel/osf_sys.c linux-2.4.22/arch/alpha/kernel/osf_sys.c
693--- linux-2.4.22/arch/alpha/kernel/osf_sys.c 2003-09-01 22:19:34.000000000 -0400
694+++ linux-2.4.22/arch/alpha/kernel/osf_sys.c 2003-09-02 19:29:41.000000000 -0400
695@@ -33,6 +33,7 @@
696 #include <linux/file.h>
697 #include <linux/types.h>
698 #include <linux/ipc.h>
699+#include <linux/grsecurity.h>
700
701 #include <asm/fpu.h>
702 #include <asm/io.h>
703@@ -240,6 +246,13 @@
704 if (!file)
705 goto out;
706 }
707+
708+ if(gr_handle_mmap(file, prot)) {
709+ fput(file);
710+ ret = -EACCES;
711+ goto out;
712+ }
713+
714 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
715 down_write(&current->mm->mmap_sem);
716 ret = do_mmap(file, addr, len, prot, flags, off);
717diff -urN linux-2.4.22/arch/alpha/kernel/ptrace.c linux-2.4.22/arch/alpha/kernel/ptrace.c
718--- linux-2.4.22/arch/alpha/kernel/ptrace.c 2003-09-01 22:19:34.000000000 -0400
719+++ linux-2.4.22/arch/alpha/kernel/ptrace.c 2003-09-02 19:29:41.000000000 -0400
720@@ -13,6 +13,7 @@
721 #include <linux/ptrace.h>
722 #include <linux/user.h>
723 #include <linux/slab.h>
724+#include <linux/grsecurity.h>
725
726 #include <asm/uaccess.h>
727 #include <asm/pgtable.h>
728@@ -275,6 +276,10 @@
729 read_unlock(&tasklist_lock);
730 if (!child)
731 goto out_notsk;
732+
733+ if(gr_handle_ptrace(child, request))
734+ goto out;
735+
736 if (request == PTRACE_ATTACH) {
737 ret = ptrace_attach(child);
738 goto out;
739diff -urN linux-2.4.22/arch/arm/config.in linux-2.4.22/arch/arm/config.in
740--- linux-2.4.22/arch/arm/config.in 2003-09-01 22:19:37.000000000 -0400
741+++ linux-2.4.22/arch/arm/config.in 2003-09-02 19:29:41.000000000 -0400
742@@ -734,3 +734,11 @@
743
744 source crypto/Config.in
745 source lib/Config.in
746+
747+mainmenu_option next_comment
748+comment 'Grsecurity'
749+bool 'Grsecurity' CONFIG_GRKERNSEC
750+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
751+ source grsecurity/Config.in
752+fi
753+endmenu
754diff -urN linux-2.4.22/arch/cris/config.in linux-2.4.22/arch/cris/config.in
755--- linux-2.4.22/arch/cris/config.in 2003-09-01 22:19:44.000000000 -0400
756+++ linux-2.4.22/arch/cris/config.in 2003-09-02 19:29:41.000000000 -0400
757@@ -275,3 +275,12 @@
758 source crypto/Config.in
759 source lib/Config.in
760 endmenu
761+
762+mainmenu_option next_comment
763+comment 'Grsecurity'
764+bool 'Grsecurity' CONFIG_GRKERNSEC
765+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
766+ source grsecurity/Config.in
767+fi
768+endmenu
769+
770diff -urN linux-2.4.22/arch/i386/config.in linux-2.4.22/arch/i386/config.in
771--- linux-2.4.22/arch/i386/config.in 2003-09-01 22:19:33.000000000 -0400
772+++ linux-2.4.22/arch/i386/config.in 2003-09-02 19:29:41.000000000 -0400
773@@ -480,3 +480,11 @@
774
775 source crypto/Config.in
776 source lib/Config.in
777+
778+mainmenu_option next_comment
779+comment 'Grsecurity'
780+bool 'Grsecurity' CONFIG_GRKERNSEC
781+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
782+ source grsecurity/Config.in
783+fi
784+endmenu
785diff -urN linux-2.4.22/arch/i386/kernel/ioport.c linux-2.4.22/arch/i386/kernel/ioport.c
786--- linux-2.4.22/arch/i386/kernel/ioport.c 2003-09-01 22:19:33.000000000 -0400
787+++ linux-2.4.22/arch/i386/kernel/ioport.c 2003-09-02 19:29:41.000000000 -0400
788@@ -14,6 +14,7 @@
789 #include <linux/smp.h>
790 #include <linux/smp_lock.h>
791 #include <linux/stddef.h>
792+#include <linux/grsecurity.h>
793
794 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
795 static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value)
796@@ -59,8 +60,16 @@
797
798 if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32))
799 return -EINVAL;
800+#ifdef CONFIG_GRKERNSEC_IO
801+ if (turn_on) {
802+ gr_handle_ioperm();
803+#else
804 if (turn_on && !capable(CAP_SYS_RAWIO))
805+#endif
806 return -EPERM;
807+#ifdef CONFIG_GRKERNSEC_IO
808+ }
809+#endif
810 /*
811 * If it's the first ioperm() call in this thread's lifetime, set the
812 * IO bitmap up. ioperm() is much less timing critical than clone(),
813@@ -109,8 +118,13 @@
814 return -EINVAL;
815 /* Trying to gain more privileges? */
816 if (level > old) {
817+#ifdef CONFIG_GRKERNSEC_IO
818+ gr_handle_iopl();
819+ return -EPERM;
820+#else
821 if (!capable(CAP_SYS_RAWIO))
822 return -EPERM;
823+#endif
824 }
825 regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12);
826 return 0;
827diff -urN linux-2.4.22/arch/i386/kernel/ptrace.c linux-2.4.22/arch/i386/kernel/ptrace.c
828--- linux-2.4.22/arch/i386/kernel/ptrace.c 2003-09-01 22:19:33.000000000 -0400
829+++ linux-2.4.22/arch/i386/kernel/ptrace.c 2003-09-02 19:29:41.000000000 -0400
830@@ -13,6 +13,7 @@
831 #include <linux/errno.h>
832 #include <linux/ptrace.h>
833 #include <linux/user.h>
834+#include <linux/grsecurity.h>
835
836 #include <asm/uaccess.h>
837 #include <asm/pgtable.h>
838@@ -177,6 +178,9 @@
839 if (pid == 1) /* you may not mess with init */
840 goto out_tsk;
841
842+ if(gr_handle_ptrace(child, request))
843+ goto out_tsk;
844+
845 if (request == PTRACE_ATTACH) {
846 ret = ptrace_attach(child);
847 goto out_tsk;
848@@ -256,6 +260,17 @@
849 if(addr < (long) &dummy->u_debugreg[4] &&
850 ((unsigned long) data) >= TASK_SIZE-3) break;
851
852+#ifdef CONFIG_GRKERNSEC
853+ if(addr >= (long) &dummy->u_debugreg[0] &&
854+ addr <= (long) &dummy->u_debugreg[3]){
855+ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
856+ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
857+ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
858+ if((type & 1) && (data & align))
859+ break;
860+ }
861+#endif
862+
863 if(addr == (long) &dummy->u_debugreg[7]) {
864 data &= ~DR_CONTROL_RESERVED;
865 for(i=0; i<4; i++)
866diff -urN linux-2.4.22/arch/i386/kernel/sys_i386.c linux-2.4.22/arch/i386/kernel/sys_i386.c
867--- linux-2.4.22/arch/i386/kernel/sys_i386.c 2003-09-01 22:19:33.000000000 -0400
868+++ linux-2.4.22/arch/i386/kernel/sys_i386.c 2003-09-02 19:29:41.000000000 -0400
869@@ -18,6 +18,7 @@
870 #include <linux/mman.h>
871 #include <linux/file.h>
872 #include <linux/utsname.h>
873+#include <linux/grsecurity.h>
874
875 #include <asm/uaccess.h>
876 #include <asm/ipc.h>
877@@ -55,6 +61,12 @@
878 goto out;
879 }
880
881+ if(gr_handle_mmap(file, prot)) {
882+ fput(file);
883+ error = -EACCES;
884+ goto out;
885+ }
886+
887 down_write(&mm->mmap_sem);
888 error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
889 up_write(&mm->mmap_sem);
890diff -urN linux-2.4.22/arch/ia64/config.in linux-2.4.22/arch/ia64/config.in
891--- linux-2.4.22/arch/ia64/config.in 2003-09-01 22:19:38.000000000 -0400
892+++ linux-2.4.22/arch/ia64/config.in 2003-09-02 19:29:41.000000000 -0400
893@@ -291,3 +291,12 @@
894 fi
895
896 endmenu
897+
898+mainmenu_option next_comment
899+comment 'Grsecurity'
900+bool 'Grsecurity' CONFIG_GRKERNSEC
901+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
902+ source grsecurity/Config.in
903+fi
904+endmenu
905+
906diff -urN linux-2.4.22/arch/ia64/kernel/ptrace.c linux-2.4.22/arch/ia64/kernel/ptrace.c
907--- linux-2.4.22/arch/ia64/kernel/ptrace.c 2003-09-01 22:19:39.000000000 -0400
908+++ linux-2.4.22/arch/ia64/kernel/ptrace.c 2003-09-02 19:29:41.000000000 -0400
909@@ -16,6 +16,7 @@
910 #include <linux/ptrace.h>
911 #include <linux/smp_lock.h>
912 #include <linux/user.h>
913+#include <linux/grsecurity.h>
914
915 #include <asm/pgtable.h>
916 #include <asm/processor.h>
917@@ -1213,6 +1214,9 @@
918 if (pid == 1) /* no messing around with init! */
919 goto out_tsk;
920
921+ if (gr_handle_ptrace(child, request))
922+ goto out_tsk;
923+
924 if (request == PTRACE_ATTACH) {
925 ret = ptrace_attach(child);
926 goto out_tsk;
927diff -urN linux-2.4.22/arch/ia64/kernel/sys_ia64.c linux-2.4.22/arch/ia64/kernel/sys_ia64.c
928--- linux-2.4.22/arch/ia64/kernel/sys_ia64.c 2003-09-01 22:19:39.000000000 -0400
929+++ linux-2.4.22/arch/ia64/kernel/sys_ia64.c 2003-09-02 19:29:41.000000000 -0400
930@@ -15,6 +15,7 @@
931 #include <linux/smp.h>
932 #include <linux/smp_lock.h>
933 #include <linux/highuid.h>
934+#include <linux/grsecurity.h>
935
936 #include <asm/shmparam.h>
937 #include <asm/uaccess.h>
938@@ -206,6 +207,11 @@
939 goto out;
940 }
941
942+ if (gr_handle_mmap(file, prot)) {
943+ addr = -EACCES;
944+ goto out;
945+ }
946+
947 down_write(&current->mm->mmap_sem);
948 addr = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
949 up_write(&current->mm->mmap_sem);
950diff -urN linux-2.4.22/arch/m68k/config.in linux-2.4.22/arch/m68k/config.in
951--- linux-2.4.22/arch/m68k/config.in 2003-09-01 22:19:37.000000000 -0400
952+++ linux-2.4.22/arch/m68k/config.in 2003-09-02 19:29:41.000000000 -0400
953@@ -564,3 +564,11 @@
954
955 source crypto/Config.in
956 source lib/Config.in
957+
958+mainmenu_option next_comment
959+comment 'Grsecurity'
960+bool 'Grsecurity' CONFIG_GRKERNSEC
961+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
962+ source grsecurity/Config.in
963+fi
964+endmenu
965diff -urN linux-2.4.22/arch/mips/config.in linux-2.4.22/arch/mips/config.in
966--- linux-2.4.22/arch/mips/config.in 2003-09-01 22:19:35.000000000 -0400
967+++ linux-2.4.22/arch/mips/config.in 2003-09-02 19:29:41.000000000 -0400
968@@ -7,3 +7,11 @@
969 define_bool CONFIG_MIPS64 n
970
971 source arch/mips/config-shared.in
972+
973+mainmenu_option next_comment
974+comment 'Grsecurity'
975+bool 'Grsecurity' CONFIG_GRKERNSEC
976+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
977+ source grsecurity/Config.in
978+fi
979+endmenu
980diff -urN linux-2.4.22/arch/mips64/config.in linux-2.4.22/arch/mips64/config.in
981--- linux-2.4.22/arch/mips64/config.in 2003-09-01 22:19:39.000000000 -0400
982+++ linux-2.4.22/arch/mips64/config.in 2003-09-02 19:29:41.000000000 -0400
983@@ -7,3 +7,11 @@
984 define_bool CONFIG_MIPS64 y
985
986 source arch/mips/config-shared.in
987+
988+mainmenu_option next_comment
989+comment 'Grsecurity'
990+bool 'Grsecurity' CONFIG_GRKERNSEC
991+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
992+ source grsecurity/Config.in
993+fi
994+endmenu
995diff -urN linux-2.4.22/arch/parisc/config.in linux-2.4.22/arch/parisc/config.in
996--- linux-2.4.22/arch/parisc/config.in 2003-09-01 22:19:39.000000000 -0400
997+++ linux-2.4.22/arch/parisc/config.in 2003-09-02 19:29:41.000000000 -0400
998@@ -198,3 +198,11 @@
999
1000 source crypto/Config.in
1001 source lib/Config.in
1002+
1003+mainmenu_option next_comment
1004+comment 'Grsecurity'
1005+bool 'Grsecurity' CONFIG_GRKERNSEC
1006+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1007+ source grsecurity/Config.in
1008+fi
1009+endmenu
1010diff -urN linux-2.4.22/arch/parisc/kernel/ioctl32.c linux-2.4.22/arch/parisc/kernel/ioctl32.c
1011--- linux-2.4.22/arch/parisc/kernel/ioctl32.c 2003-09-01 22:19:44.000000000 -0400
1012+++ linux-2.4.22/arch/parisc/kernel/ioctl32.c 2003-09-02 19:29:41.000000000 -0400
1013@@ -1434,7 +1434,11 @@
1014 * To have permissions to do most of the vt ioctls, we either have
1015 * to be the owner of the tty, or super-user.
1016 */
1017+#ifdef CONFIG_GRKERNSEC
1018+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1019+#else
1020 if (current->tty == tty || suser())
1021+#endif
1022 return 1;
1023 return 0;
1024 }
1025diff -urN linux-2.4.22/arch/parisc/kernel/ptrace.c linux-2.4.22/arch/parisc/kernel/ptrace.c
1026--- linux-2.4.22/arch/parisc/kernel/ptrace.c 2003-09-01 22:19:44.000000000 -0400
1027+++ linux-2.4.22/arch/parisc/kernel/ptrace.c 2003-09-02 19:29:41.000000000 -0400
1028@@ -15,7 +15,7 @@
1029 #include <linux/ptrace.h>
1030 #include <linux/user.h>
1031 #include <linux/personality.h>
1032-
1033+#include <linux/grsecurity.h>
1034 #include <asm/uaccess.h>
1035 #include <asm/pgtable.h>
1036 #include <asm/system.h>
1037@@ -119,6 +119,9 @@
1038 if (pid == 1) /* no messing around with init! */
1039 goto out_tsk;
1040
1041+ if (gr_handle_ptrace(child, request))
1042+ goto out_tsk;
1043+
1044 if (request == PTRACE_ATTACH) {
1045 ret = ptrace_attach(child);
1046 goto out_tsk;
1047diff -urN linux-2.4.22/arch/parisc/kernel/sys_parisc.c linux-2.4.22/arch/parisc/kernel/sys_parisc.c
1048--- linux-2.4.22/arch/parisc/kernel/sys_parisc.c 2003-09-01 22:19:44.000000000 -0400
1049+++ linux-2.4.22/arch/parisc/kernel/sys_parisc.c 2003-09-02 19:29:41.000000000 -0400
1050@@ -12,6 +12,7 @@
1051 #include <linux/mman.h>
1052 #include <linux/shm.h>
1053 #include <linux/smp_lock.h>
1054+#include <linux/grsecurity.h>
1055
1056 int sys_pipe(int *fildes)
1057 {
1058@@ -104,6 +110,11 @@
1059 goto out;
1060 }
1061
1062+ if (gr_handle_mmap(file, prot)) {
1063+ fput(file);
1064+ return -EACCES;
1065+ }
1066+
1067 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1068
1069 down_write(&current->mm->mmap_sem);
1070diff -urN linux-2.4.22/arch/parisc/kernel/sys_parisc32.c linux-2.4.22/arch/parisc/kernel/sys_parisc32.c
1071--- linux-2.4.22/arch/parisc/kernel/sys_parisc32.c 2003-09-01 22:19:44.000000000 -0400
1072+++ linux-2.4.22/arch/parisc/kernel/sys_parisc32.c 2003-09-02 19:29:41.000000000 -0400
1073@@ -50,6 +50,7 @@
1074 #include <linux/highmem.h>
1075 #include <linux/highuid.h>
1076 #include <linux/mman.h>
1077+#include <linux/grsecurity.h>
1078
1079 #include <asm/types.h>
1080 #include <asm/uaccess.h>
1081@@ -177,6 +178,11 @@
1082 struct file *file;
1083 int retval;
1084 int i;
1085+#ifdef CONFIG_GRKERNSEC
1086+ struct file *old_exec_file;
1087+ struct acl_subject_label *old_acl;
1088+ struct rlimit old_rlim[RLIM_NLIMITS];
1089+#endif
1090
1091 file = open_exec(filename);
1092
1093@@ -184,6 +190,20 @@
1094 if (IS_ERR(file))
1095 return retval;
1096
1097+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
1098+
1099+ if (gr_handle_nproc()) {
1100+ allow_write_access(file);
1101+ fput(file);
1102+ return -EAGAIN;
1103+ }
1104+
1105+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
1106+ allow_write_access(file);
1107+ fput(file);
1108+ return -EACCES;
1109+ }
1110+
1111 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
1112 memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
1113
1114@@ -209,11 +234,24 @@
1115 if (retval < 0)
1116 goto out;
1117
1118+ if (!gr_tpe_allow(file)) {
1119+ retval = -EACCES;
1120+ goto out;
1121+ }
1122+
1123+ if (gr_check_crash_exec(file)) {
1124+ retval = -EACCES;
1125+ goto out;
1126+ }
1127+
1128 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
1129 if (retval < 0)
1130 goto out;
1131
1132 bprm.exec = bprm.p;
1133+
1134+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
1135+
1136 retval = copy_strings32(bprm.envc, envp, &bprm);
1137 if (retval < 0)
1138 goto out;
1139@@ -222,11 +260,32 @@
1140 if (retval < 0)
1141 goto out;
1142
1143+#ifdef CONFIG_GRKERNSEC
1144+ old_acl = current->acl;
1145+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
1146+ old_exec_file = current->exec_file;
1147+ get_file(file);
1148+ current->exec_file = file;
1149+#endif
1150+
1151+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
1152+
1153 retval = search_binary_handler(&bprm,regs);
1154- if (retval >= 0)
1155+ if (retval >= 0) {
1156+#ifdef CONFIG_GRKERNSEC
1157+ if (old_exec_file)
1158+ fput(old_exec_file);
1159+#endif
1160 /* execve success */
1161 return retval;
1162+ }
1163
1164+#ifdef CONFIG_GRKERNSEC
1165+ current->acl = old_acl;
1166+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
1167+ fput(current->exec_file);
1168+ current->exec_file = old_exec_file;
1169+#endif
1170 out:
1171 /* Something went wrong, return the inode and free the argument pages*/
1172 allow_write_access(bprm.file);
1173diff -urN linux-2.4.22/arch/ppc/config.in linux-2.4.22/arch/ppc/config.in
1174--- linux-2.4.22/arch/ppc/config.in 2003-09-01 22:19:36.000000000 -0400
1175+++ linux-2.4.22/arch/ppc/config.in 2003-09-02 19:29:41.000000000 -0400
1176@@ -488,3 +488,12 @@
1177 bool 'Support for early boot texts over serial port' CONFIG_SERIAL_TEXT_DEBUG
1178 fi
1179 endmenu
1180+
1181+mainmenu_option next_comment
1182+comment 'Grsecurity'
1183+bool 'Grsecurity' CONFIG_GRKERNSEC
1184+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1185+ source grsecurity/Config.in
1186+fi
1187+endmenu
1188+
1189diff -urN linux-2.4.22/arch/ppc/kernel/ptrace.c linux-2.4.22/arch/ppc/kernel/ptrace.c
1190--- linux-2.4.22/arch/ppc/kernel/ptrace.c 2003-09-01 22:19:36.000000000 -0400
1191+++ linux-2.4.22/arch/ppc/kernel/ptrace.c 2003-09-02 19:29:41.000000000 -0400
1192@@ -24,6 +24,7 @@
1193 #include <linux/errno.h>
1194 #include <linux/ptrace.h>
1195 #include <linux/user.h>
1196+#include <linux/grsecurity.h>
1197
1198 #include <asm/uaccess.h>
1199 #include <asm/page.h>
1200@@ -195,6 +196,9 @@
1201 if (pid == 1) /* you may not mess with init */
1202 goto out_tsk;
1203
1204+ if (gr_handle_ptrace(child, request))
1205+ goto out_tsk;
1206+
1207 if (request == PTRACE_ATTACH) {
1208 ret = ptrace_attach(child);
1209 goto out_tsk;
1210diff -urN linux-2.4.22/arch/ppc/kernel/syscalls.c linux-2.4.22/arch/ppc/kernel/syscalls.c
1211--- linux-2.4.22/arch/ppc/kernel/syscalls.c 2003-09-01 22:19:36.000000000 -0400
1212+++ linux-2.4.22/arch/ppc/kernel/syscalls.c 2003-09-02 19:29:41.000000000 -0400
1213@@ -35,6 +35,7 @@
1214 #include <linux/ipc.h>
1215 #include <linux/utsname.h>
1216 #include <linux/file.h>
1217+#include <linux/grsecurity.h>
1218
1219 #include <asm/uaccess.h>
1220 #include <asm/ipc.h>
1221@@ -175,6 +176,12 @@
1222 goto out;
1223 }
1224
1225+ if (gr_handle_mmap(file, prot)) {
1226+ fput(file);
1227+ ret = -EACCES;
1228+ goto out;
1229+ }
1230+
1231 down_write(&current->mm->mmap_sem);
1232 ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1233 up_write(&current->mm->mmap_sem);
1234diff -urN linux-2.4.22/arch/ppc64/kernel/ioctl32.c linux-2.4.22/arch/ppc64/kernel/ioctl32.c
1235--- linux-2.4.22/arch/ppc64/kernel/ioctl32.c 2003-09-01 22:19:33.000000000 -0400
1236+++ linux-2.4.22/arch/ppc64/kernel/ioctl32.c 2003-09-02 19:29:41.000000000 -0400
1237@@ -1800,7 +1800,11 @@
1238 * To have permissions to do most of the vt ioctls, we either have
1239 * to be the owner of the tty, or super-user.
1240 */
1241+#ifdef CONFIG_GRKERNSEC
1242+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1243+#else
1244 if (current->tty == tty || suser())
1245+#endif
1246 return 1;
1247 return 0;
1248 }
1249diff -urN linux-2.4.22/arch/s390/config.in linux-2.4.22/arch/s390/config.in
1250--- linux-2.4.22/arch/s390/config.in 2003-09-01 22:19:39.000000000 -0400
1251+++ linux-2.4.22/arch/s390/config.in 2003-09-02 19:29:41.000000000 -0400
1252@@ -81,3 +81,11 @@
1253
1254 source crypto/Config.in
1255 source lib/Config.in
1256+
1257+mainmenu_option next_comment
1258+comment 'Grsecurity'
1259+bool 'Grsecurity' CONFIG_GRKERNSEC
1260+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1261+ source grsecurity/Config.in
1262+fi
1263+endmenu
1264diff -urN linux-2.4.22/arch/s390x/config.in linux-2.4.22/arch/s390x/config.in
1265--- linux-2.4.22/arch/s390x/config.in 2003-09-01 22:19:44.000000000 -0400
1266+++ linux-2.4.22/arch/s390x/config.in 2003-09-02 19:29:41.000000000 -0400
1267@@ -85,3 +85,11 @@
1268
1269 source crypto/Config.in
1270 source lib/Config.in
1271+
1272+mainmenu_option next_comment
1273+comment 'Grsecurity'
1274+bool 'Grsecurity' CONFIG_GRKERNSEC
1275+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1276+ source grsecurity/Config.in
1277+fi
1278+endmenu
1279diff -urN linux-2.4.22/arch/sh/config.in linux-2.4.22/arch/sh/config.in
1280--- linux-2.4.22/arch/sh/config.in 2003-09-01 22:19:38.000000000 -0400
1281+++ linux-2.4.22/arch/sh/config.in 2003-09-02 19:29:41.000000000 -0400
1282@@ -469,3 +469,11 @@
1283
1284 source crypto/Config.in
1285 source lib/Config.in
1286+
1287+mainmenu_option next_comment
1288+comment 'Grsecurity'
1289+bool 'Grsecurity' CONFIG_GRKERNSEC
1290+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1291+ source grsecurity/Config.in
1292+fi
1293+endmenu
1294diff -urN linux-2.4.22/arch/sparc/boot/Makefile linux-2.4.22/arch/sparc/boot/Makefile
1295--- linux-2.4.22/arch/sparc/boot/Makefile 2003-09-01 22:19:34.000000000 -0400
1296+++ linux-2.4.22/arch/sparc/boot/Makefile 2003-09-02 19:29:41.000000000 -0400
1297@@ -24,7 +24,7 @@
1298
1299 BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o
1300 BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
1301- $(DRIVERS) $(NETWORKS)
1302+ $(DRIVERS) $(NETWORKS) $(GRSECURITY)
1303
1304 # I wanted to make this depend upon BTOBJS so that a parallel
1305 # build would work, but this fails because $(HEAD) cannot work
1306diff -urN linux-2.4.22/arch/sparc/config.in linux-2.4.22/arch/sparc/config.in
1307--- linux-2.4.22/arch/sparc/config.in 2003-09-01 22:19:34.000000000 -0400
1308+++ linux-2.4.22/arch/sparc/config.in 2003-09-02 19:29:41.000000000 -0400
1309@@ -277,3 +277,11 @@
1310
1311 source crypto/Config.in
1312 source lib/Config.in
1313+
1314+mainmenu_option next_comment
1315+comment 'Grsecurity'
1316+bool 'Grsecurity' CONFIG_GRKERNSEC
1317+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1318+ source grsecurity/Config.in
1319+fi
1320+endmenu
1321diff -urN linux-2.4.22/arch/sparc/kernel/ptrace.c linux-2.4.22/arch/sparc/kernel/ptrace.c
1322--- linux-2.4.22/arch/sparc/kernel/ptrace.c 2003-09-01 22:19:34.000000000 -0400
1323+++ linux-2.4.22/arch/sparc/kernel/ptrace.c 2003-09-02 19:29:41.000000000 -0400
1324@@ -17,6 +17,7 @@
1325 #include <linux/user.h>
1326 #include <linux/smp.h>
1327 #include <linux/smp_lock.h>
1328+#include <linux/grsecurity.h>
1329
1330 #include <asm/pgtable.h>
1331 #include <asm/system.h>
1332@@ -310,6 +311,9 @@
1333 goto out;
1334 }
1335
1336+ if(gr_handle_ptrace(child, request))
1337+ goto out_tsk;
1338+
1339 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
1340 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
1341 if (ptrace_attach(child)) {
1342diff -urN linux-2.4.22/arch/sparc/kernel/sys_sparc.c linux-2.4.22/arch/sparc/kernel/sys_sparc.c
1343--- linux-2.4.22/arch/sparc/kernel/sys_sparc.c 2003-09-01 22:19:34.000000000 -0400
1344+++ linux-2.4.22/arch/sparc/kernel/sys_sparc.c 2003-09-02 19:29:41.000000000 -0400
1345@@ -20,6 +20,7 @@
1346 #include <linux/utsname.h>
1347 #include <linux/smp.h>
1348 #include <linux/smp_lock.h>
1349+#include <linux/grsecurity.h>
1350
1351 #include <asm/uaccess.h>
1352 #include <asm/ipc.h>
1353@@ -243,6 +256,12 @@
1354 if (len > TASK_SIZE - PAGE_SIZE || addr + len > TASK_SIZE - PAGE_SIZE)
1355 goto out_putf;
1356
1357+ if (gr_handle_mmap(file, prot)) {
1358+ fput(file);
1359+ retval = -EACCES;
1360+ goto out;
1361+ }
1362+
1363 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1364
1365 down_write(&current->mm->mmap_sem);
1366diff -urN linux-2.4.22/arch/sparc64/config.in linux-2.4.22/arch/sparc64/config.in
1367--- linux-2.4.22/arch/sparc64/config.in 2003-09-01 22:19:37.000000000 -0400
1368+++ linux-2.4.22/arch/sparc64/config.in 2003-09-02 19:29:41.000000000 -0400
1369@@ -311,3 +311,11 @@
1370
1371 source crypto/Config.in
1372 source lib/Config.in
1373+
1374+mainmenu_option next_comment
1375+comment 'Grsecurity'
1376+bool 'Grsecurity' CONFIG_GRKERNSEC
1377+if [ "$CONFIG_GRKERNSEC" = "y" ]; then
1378+ source grsecurity/Config.in
1379+fi
1380+endmenu
1381diff -urN linux-2.4.22/arch/sparc64/kernel/ioctl32.c linux-2.4.22/arch/sparc64/kernel/ioctl32.c
1382--- linux-2.4.22/arch/sparc64/kernel/ioctl32.c 2003-09-01 22:19:37.000000000 -0400
1383+++ linux-2.4.22/arch/sparc64/kernel/ioctl32.c 2003-09-02 19:29:41.000000000 -0400
1384@@ -2046,7 +2046,11 @@
1385 * To have permissions to do most of the vt ioctls, we either have
1386 * to be the owner of the tty, or super-user.
1387 */
1388+#ifdef CONFIG_GRKERNSEC
1389+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1390+#else
1391 if (current->tty == tty || suser())
1392+#endif
1393 return 1;
1394 return 0;
1395 }
1396diff -urN linux-2.4.22/arch/sparc64/kernel/ptrace.c linux-2.4.22/arch/sparc64/kernel/ptrace.c
1397--- linux-2.4.22/arch/sparc64/kernel/ptrace.c 2003-09-01 22:19:37.000000000 -0400
1398+++ linux-2.4.22/arch/sparc64/kernel/ptrace.c 2003-09-02 19:29:41.000000000 -0400
1399@@ -18,6 +18,7 @@
1400 #include <linux/user.h>
1401 #include <linux/smp.h>
1402 #include <linux/smp_lock.h>
1403+#include <linux/grsecurity.h>
1404
1405 #include <asm/asi.h>
1406 #include <asm/pgtable.h>
1407@@ -161,6 +162,11 @@
1408 goto out;
1409 }
1410
1411+ if (gr_handle_ptrace(child, (long)request)) {
1412+ pt_error_return(regs, EPERM);
1413+ goto out;
1414+ }
1415+
1416 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
1417 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
1418 if (ptrace_attach(child)) {
1419diff -urN linux-2.4.22/arch/sparc64/kernel/sys_sparc.c linux-2.4.22/arch/sparc64/kernel/sys_sparc.c
1420--- linux-2.4.22/arch/sparc64/kernel/sys_sparc.c 2003-09-01 22:19:37.000000000 -0400
1421+++ linux-2.4.22/arch/sparc64/kernel/sys_sparc.c 2003-09-02 19:29:41.000000000 -0400
1422@@ -24,6 +24,7 @@
1423 #include <linux/slab.h>
1424 #include <linux/ipc.h>
1425 #include <linux/personality.h>
1426+#include <linux/grsecurity.h>
1427
1428 #include <asm/uaccess.h>
1429 #include <asm/ipc.h>
1430@@ -289,6 +297,12 @@
1431 if (!file)
1432 goto out;
1433 }
1434+
1435+ if (gr_handle_mmap(file, prot)) {
1436+ retval = -EACCES;
1437+ goto out_putf;
1438+ }
1439+
1440 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
1441 len = PAGE_ALIGN(len);
1442 retval = -EINVAL;
1443diff -urN linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c
1444--- linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c 2003-09-01 22:19:37.000000000 -0400
1445+++ linux-2.4.22/arch/sparc64/kernel/sys_sparc32.c 2003-09-02 19:29:41.000000000 -0400
1446@@ -52,6 +52,8 @@
1447 #include <linux/sysctl.h>
1448 #include <linux/dnotify.h>
1449 #include <linux/netfilter_ipv4/ip_tables.h>
1450+#include <linux/random.h>
1451+#include <linux/grsecurity.h>
1452
1453 #include <asm/types.h>
1454 #include <asm/ipc.h>
1455@@ -3233,6 +3235,11 @@
1456 struct file * file;
1457 int retval;
1458 int i;
1459+#ifdef CONFIG_GRKERNSEC
1460+ struct file *old_exec_file;
1461+ struct acl_subject_label *old_acl;
1462+ struct rlimit old_rlim[RLIM_NLIMITS];
1463+#endif
1464
1465 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
1466 memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0]));
1467@@ -3243,6 +3255,20 @@
1468 if (IS_ERR(file))
1469 return retval;
1470
1471+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
1472+
1473+ if (gr_handle_nproc()) {
1474+ allow_write_access(file);
1475+ fput(file);
1476+ return -EAGAIN;
1477+ }
1478+
1479+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
1480+ allow_write_access(file);
1481+ fput(file);
1482+ return -EACCES;
1483+ }
1484+
1485 bprm.file = file;
1486 bprm.filename = filename;
1487 bprm.sh_bang = 0;
1488@@ -3263,11 +3289,24 @@
1489 if (retval < 0)
1490 goto out;
1491
1492+ if(!gr_tpe_allow(file)) {
1493+ retval = -EACCES;
1494+ goto out;
1495+ }
1496+
1497+ if (gr_check_crash_exec(file)) {
1498+ retval = -EACCES;
1499+ goto out;
1500+ }
1501+
1502 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
1503 if (retval < 0)
1504 goto out;
1505
1506 bprm.exec = bprm.p;
1507+
1508+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
1509+
1510 retval = copy_strings32(bprm.envc, envp, &bprm);
1511 if (retval < 0)
1512 goto out;
1513@@ -3276,11 +3315,32 @@
1514 if (retval < 0)
1515 goto out;
1516
1517+#ifdef CONFIG_GRKERNSEC
1518+ old_acl = current->acl;
1519+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
1520+ old_exec_file = current->exec_file;
1521+ get_file(file);
1522+ current->exec_file = file;
1523+#endif
1524+
1525+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
1526+
1527 retval = search_binary_handler(&bprm, regs);
1528- if (retval >= 0)
1529+ if (retval >= 0) {
1530+#ifdef CONFIG_GRKERNSEC
1531+ if (old_exec_file)
1532+ fput(old_exec_file);
1533+#endif
1534 /* execve success */
1535 return retval;
1536+ }
1537
1538+#ifdef CONFIG_GRKERNSEC
1539+ current->acl = old_acl;
1540+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
1541+ fput(current->exec_file);
1542+ current->exec_file = old_exec_file;
1543+#endif
1544 out:
1545 /* Something went wrong, return the inode and free the argument pages*/
1546 allow_write_access(bprm.file);
1547diff -urN linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c
1548--- linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c 2003-09-01 22:19:33.000000000 -0400
1549+++ linux-2.4.22/arch/x86_64/ia32/ia32_ioctl.c 2003-09-02 19:29:41.000000000 -0400
1550@@ -1932,7 +1932,11 @@
1551 * To have permissions to do most of the vt ioctls, we either have
1552 * to be the owner of the tty, or super-user.
1553 */
1554+#ifdef CONFIG_GRKERNSEC
1555+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1556+#else
1557 if (current->tty == tty || suser())
1558+#endif
1559 return 1;
1560 return 0;
1561 }
1562diff -urN linux-2.4.22/drivers/char/mem.c linux-2.4.22/drivers/char/mem.c
1563--- linux-2.4.22/drivers/char/mem.c 2003-09-01 22:19:16.000000000 -0400
1564+++ linux-2.4.22/drivers/char/mem.c 2003-09-02 19:29:41.000000000 -0400
1565@@ -21,6 +21,7 @@
1566 #include <linux/raw.h>
1567 #include <linux/tty.h>
1568 #include <linux/capability.h>
1569+#include <linux/grsecurity.h>
1570
1571 #include <asm/uaccess.h>
1572 #include <asm/io.h>
1573@@ -41,6 +42,10 @@
1574 #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
1575 extern void tapechar_init(void);
1576 #endif
1577+
1578+#ifdef CONFIG_GRKERNSEC
1579+extern struct file_operations grsec_fops;
1580+#endif
1581
1582 static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
1583 const char * buf, size_t count, loff_t *ppos)
1584@@ -114,6 +119,11 @@
1585 unsigned long p = *ppos;
1586 unsigned long end_mem;
1587
1588+#ifdef CONFIG_GRKERNSEC_KMEM
1589+ gr_handle_mem_write();
1590+ return -EPERM;
1591+#endif
1592+
1593 end_mem = __pa(high_memory);
1594 if (p >= end_mem)
1595 return 0;
1596@@ -186,6 +196,12 @@
1597 {
1598 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1599
1600+#ifdef CONFIG_GRKERNSEC_KMEM
1601+ if (gr_handle_mem_mmap(offset, vma))
1602+ return -EPERM;
1603+#endif
1604+
1605+
1606 /*
1607 * Accessing memory above the top the kernel knows about or
1608 * through a file pointer that was marked O_SYNC will be
1609@@ -285,6 +301,11 @@
1610 ssize_t virtr = 0;
1611 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
1612
1613+#ifdef CONFIG_GRKERNSEC_KMEM
1614+ gr_handle_kmem_write();
1615+ return -EPERM;
1616+#endif
1617+
1618 if (p < (unsigned long) high_memory) {
1619 wrote = count;
1620 if (count > (unsigned long) high_memory - p)
1621@@ -517,6 +538,15 @@
1622
1623 static int open_port(struct inode * inode, struct file * filp)
1624 {
1625+#ifdef CONFIG_GRKERNSEC_KMEM
1626+ gr_handle_open_port();
1627+ return -EPERM;
1628+#endif
1629+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
1630+}
1631+
1632+static int open_mem(struct inode * inode, struct file * filp)
1633+{
1634 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
1635 }
1636
1637@@ -574,6 +604,11 @@
1638 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1639 unsigned long size = vma->vm_end - vma->vm_start;
1640
1641+#ifdef CONFIG_GRKERNSEC_KMEM
1642+ if (gr_handle_mem_mmap(offset, vma))
1643+ return -EPERM;
1644+#endif
1645+
1646 /*
1647 * If the user is not attempting to mmap a high memory address then
1648 * the standard mmap_mem mechanism will work. High memory addresses
1649@@ -609,7 +644,6 @@
1650 #define full_lseek null_lseek
1651 #define write_zero write_null
1652 #define read_full read_zero
1653-#define open_mem open_port
1654 #define open_kmem open_mem
1655
1656 static struct file_operations mem_fops = {
1657@@ -685,6 +719,11 @@
1658 case 9:
1659 filp->f_op = &urandom_fops;
1660 break;
1661+#ifdef CONFIG_GRKERNSEC
1662+ case 10:
1663+ filp->f_op = &grsec_fops;
1664+ break;
1665+#endif
1666 default:
1667 return -ENXIO;
1668 }
1669@@ -711,7 +750,10 @@
1670 {5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
1671 {7, "full", S_IRUGO | S_IWUGO, &full_fops},
1672 {8, "random", S_IRUGO | S_IWUSR, &random_fops},
1673- {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}
1674+ {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops},
1675+#ifdef CONFIG_GRKERNSEC
1676+ {10,"grsec", S_IRUSR | S_IWUGO, &grsec_fops}
1677+#endif
1678 };
1679 int i;
1680
1681diff -urN linux-2.4.22/drivers/char/random.c linux-2.4.22/drivers/char/random.c
1682--- linux-2.4.22/drivers/char/random.c 2003-09-01 22:19:16.000000000 -0400
1683+++ linux-2.4.22/drivers/char/random.c 2003-09-02 19:29:42.000000000 -0400
1684@@ -262,9 +262,15 @@
1685 /*
1686 * Configuration information
1687 */
1688+#ifdef CONFIG_GRKERNSEC_RANDNET
1689+#define DEFAULT_POOL_SIZE 1024
1690+#define SECONDARY_POOL_SIZE 256
1691+#define BATCH_ENTROPY_SIZE 512
1692+#else
1693 #define DEFAULT_POOL_SIZE 512
1694 #define SECONDARY_POOL_SIZE 128
1695 #define BATCH_ENTROPY_SIZE 256
1696+#endif
1697 #define USE_SHA
1698
1699 /*
1700@@ -389,6 +395,7 @@
1701 /*
1702 * Static global variables
1703 */
1704+
1705 static struct entropy_store *random_state; /* The default global store */
1706 static struct entropy_store *sec_random_state; /* secondary store */
1707 static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
1708@@ -2202,6 +2209,29 @@
1709 return halfMD4Transform(hash, keyptr->secret);
1710 }
1711
1712+#ifdef CONFIG_GRKERNSEC
1713+/* the following function is provided by PaX under the GPL */
1714+unsigned long get_random_long(void)
1715+{
1716+ static time_t rekey_time;
1717+ static __u32 secret[12];
1718+ time_t t;
1719+
1720+ /*
1721+ * Pick a random secret every REKEY_INTERVAL seconds
1722+ */
1723+ t = CURRENT_TIME;
1724+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
1725+ rekey_time = t;
1726+ get_random_bytes(secret, sizeof(secret));
1727+ }
1728+
1729+ secret[1] = halfMD4Transform(secret+8, secret);
1730+ secret[0] = halfMD4Transform(secret+8, secret);
1731+ return *(unsigned long *)secret;
1732+}
1733+#endif
1734+
1735 #ifdef CONFIG_SYN_COOKIES
1736 /*
1737 * Secure SYN cookie computation. This is the algorithm worked out by
1738diff -urN linux-2.4.22/drivers/char/tty_io.c linux-2.4.22/drivers/char/tty_io.c
1739--- linux-2.4.22/drivers/char/tty_io.c 2003-09-01 22:19:16.000000000 -0400
1740+++ linux-2.4.22/drivers/char/tty_io.c 2003-09-02 19:29:42.000000000 -0400
1741@@ -99,7 +99,7 @@
1742 #include <linux/vt_kern.h>
1743 #include <linux/selection.h>
1744 #include <linux/devfs_fs_kernel.h>
1745-
1746+#include <linux/grsecurity.h>
1747 #include <linux/kmod.h>
1748
1749 #ifdef CONFIG_VT
1750@@ -1402,7 +1402,11 @@
1751 retval = -ENODEV;
1752 filp->f_flags = saved_flags;
1753
1754+#ifdef CONFIG_GRKERNSEC
1755+ if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_TTY_CONFIG))
1756+#else
1757 if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser())
1758+#endif
1759 retval = -EBUSY;
1760
1761 if (retval) {
1762@@ -1504,7 +1508,11 @@
1763 {
1764 char ch, mbz = 0;
1765
1766+#ifdef CONFIG_GRKERNSEC
1767+ if ((current->tty != tty) && !capable(CAP_SYS_TTY_CONFIG))
1768+#else
1769 if ((current->tty != tty) && !suser())
1770+#endif
1771 return -EPERM;
1772 if (get_user(ch, arg))
1773 return -EFAULT;
1774@@ -1542,7 +1550,11 @@
1775 if (inode->i_rdev == SYSCONS_DEV ||
1776 inode->i_rdev == CONSOLE_DEV) {
1777 struct file *f;
1778+#ifdef CONFIG_GRKERNSEC
1779+ if (!capable(CAP_SYS_TTY_CONFIG))
1780+#else
1781 if (!suser())
1782+#endif
1783 return -EPERM;
1784 spin_lock(&redirect_lock);
1785 f = redirect;
1786@@ -1594,7 +1606,11 @@
1787 * This tty is already the controlling
1788 * tty for another session group!
1789 */
1790+#ifdef CONFIG_GRKERNSEC
1791+ if ((arg == 1) && capable(CAP_SYS_ADMIN)) {
1792+#else
1793 if ((arg == 1) && suser()) {
1794+#endif
1795 /*
1796 * Steal it away
1797 */
1798diff -urN linux-2.4.22/drivers/char/vt.c linux-2.4.22/drivers/char/vt.c
1799--- linux-2.4.22/drivers/char/vt.c 2003-09-01 22:19:16.000000000 -0400
1800+++ linux-2.4.22/drivers/char/vt.c 2003-09-02 19:29:42.000000000 -0400
1801@@ -32,6 +32,7 @@
1802 #include <linux/vt_kern.h>
1803 #include <linux/kbd_diacr.h>
1804 #include <linux/selection.h>
1805+#include <linux/grsecurity.h>
1806
1807 #ifdef CONFIG_FB_COMPAT_XPMAC
1808 #include <asm/vc_ioctl.h>
1809@@ -443,7 +444,11 @@
1810 * to be the owner of the tty, or super-user.
1811 */
1812 perm = 0;
1813+#ifdef CONFIG_GRKERNSEC
1814+ if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1815+#else
1816 if (current->tty == tty || suser())
1817+#endif
1818 perm = 1;
1819
1820 kbd = kbd_table + console;
1821@@ -1038,12 +1043,20 @@
1822 return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm);
1823
1824 case VT_LOCKSWITCH:
1825+#ifdef CONFIG_GRKERNSEC
1826+ if (!capable(CAP_SYS_TTY_CONFIG))
1827+#else
1828 if (!suser())
1829+#endif
1830 return -EPERM;
1831 vt_dont_switch = 1;
1832 return 0;
1833 case VT_UNLOCKSWITCH:
1834+#ifdef CONFIG_GRKERNSEC
1835+ if (!capable(CAP_SYS_TTY_CONFIG))
1836+#else
1837 if (!suser())
1838+#endif
1839 return -EPERM;
1840 vt_dont_switch = 0;
1841 return 0;
1842diff -urN linux-2.4.22/drivers/pci/proc.c linux-2.4.22/drivers/pci/proc.c
1843--- linux-2.4.22/drivers/pci/proc.c 2003-09-01 22:19:22.000000000 -0400
1844+++ linux-2.4.22/drivers/pci/proc.c 2003-09-02 19:29:42.000000000 -0400
1845@@ -562,7 +562,15 @@
1846 pci_for_each_dev(dev) {
1847 pci_proc_attach_device(dev);
1848 }
1849+#ifdef CONFIG_GRKERNSEC_PROC_ADD
1850+#ifdef CONFIG_GRKERNSEC_PROC_USER
1851+ entry = create_proc_entry("pci", S_IRUSR, NULL);
1852+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
1853+ entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL);
1854+#endif
1855+#else
1856 entry = create_proc_entry("pci", 0, NULL);
1857+#endif
1858 if (entry)
1859 entry->proc_fops = &proc_pci_operations;
1860 }
1861diff -urN linux-2.4.22/fs/binfmt_aout.c linux-2.4.22/fs/binfmt_aout.c
1862--- linux-2.4.22/fs/binfmt_aout.c 2003-09-01 22:19:01.000000000 -0400
1863+++ linux-2.4.22/fs/binfmt_aout.c 2003-09-02 19:29:42.000000000 -0400
1864@@ -5,6 +5,7 @@
1865 */
1866
1867 #include <linux/module.h>
1868+#include <linux/config.h>
1869
1870 #include <linux/sched.h>
1871 #include <linux/kernel.h>
1872@@ -113,10 +114,12 @@
1873 /* If the size of the dump file exceeds the rlimit, then see what would happen
1874 if we wrote the stack, but not the data area. */
1875 #ifdef __sparc__
1876+ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize);
1877 if ((dump.u_dsize+dump.u_ssize) >
1878 current->rlim[RLIMIT_CORE].rlim_cur)
1879 dump.u_dsize = 0;
1880 #else
1881+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE);
1882 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
1883 current->rlim[RLIMIT_CORE].rlim_cur)
1884 dump.u_dsize = 0;
1885@@ -124,10 +127,12 @@
1886
1887 /* Make sure we have enough room to write the stack and data areas. */
1888 #ifdef __sparc__
1889+ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize);
1890 if ((dump.u_ssize) >
1891 current->rlim[RLIMIT_CORE].rlim_cur)
1892 dump.u_ssize = 0;
1893 #else
1894+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE);
1895 if ((dump.u_ssize+1) * PAGE_SIZE >
1896 current->rlim[RLIMIT_CORE].rlim_cur)
1897 dump.u_ssize = 0;
1898@@ -276,6 +281,8 @@
1899 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
1900 if (rlim >= RLIM_INFINITY)
1901 rlim = ~0;
1902+
1903+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss);
1904 if (ex.a_data + ex.a_bss > rlim)
1905 return -ENOMEM;
1906
1907diff -urN linux-2.4.22/fs/binfmt_elf.c linux-2.4.22/fs/binfmt_elf.c
1908--- linux-2.4.22/fs/binfmt_elf.c 2003-09-01 22:19:00.000000000 -0400
1909+++ linux-2.4.22/fs/binfmt_elf.c 2003-09-02 19:29:42.000000000 -0400
1910@@ -11,6 +11,7 @@
1911
1912 #include <linux/module.h>
1913
1914+#include <linux/config.h>
1915 #include <linux/fs.h>
1916 #include <linux/stat.h>
1917 #include <linux/sched.h>
1918@@ -33,10 +34,13 @@
1919 #include <linux/smp_lock.h>
1920 #include <linux/compiler.h>
1921 #include <linux/highmem.h>
1922+#include <linux/random.h>
1923+#include <linux/grsecurity.h>
1924
1925 #include <asm/uaccess.h>
1926 #include <asm/param.h>
1927 #include <asm/pgalloc.h>
1928+#include <asm/system.h>
1929
1930 #define DLINFO_ITEMS 13
1931
1932@@ -1026,8 +1184,11 @@
1933 #undef DUMP_SEEK
1934
1935 #define DUMP_WRITE(addr, nr) \
1936+ do { \
1937+ gr_learn_resource(current, RLIMIT_CORE, size + (nr)); \
1938 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
1939- goto end_coredump;
1940+ goto end_coredump; \
1941+ } while (0);
1942 #define DUMP_SEEK(off) \
1943 if (!dump_seek(file, (off))) \
1944 goto end_coredump;
1945diff -urN linux-2.4.22/fs/buffer.c linux-2.4.22/fs/buffer.c
1946--- linux-2.4.22/fs/buffer.c 2003-09-01 22:19:00.000000000 -0400
1947+++ linux-2.4.22/fs/buffer.c 2003-09-02 19:29:42.000000000 -0400
1948@@ -1810,6 +1810,9 @@
1949 int err;
1950
1951 err = -EFBIG;
1952+
1953+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size);
1954+
1955 limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
1956 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
1957 send_sig(SIGXFSZ, current, 0);
1958diff -urN linux-2.4.22/fs/exec.c linux-2.4.22/fs/exec.c
1959--- linux-2.4.22/fs/exec.c 2003-09-01 22:19:00.000000000 -0400
1960+++ linux-2.4.22/fs/exec.c 2003-09-02 19:29:42.000000000 -0400
1961@@ -43,6 +43,9 @@
1962 #include <asm/uaccess.h>
1963 #include <asm/pgalloc.h>
1964 #include <asm/mmu_context.h>
1965+#include <linux/major.h>
1966+#include <linux/random.h>
1967+#include <linux/grsecurity.h>
1968
1969 #ifdef CONFIG_KMOD
1970 #include <linux/kmod.h>
1971@@ -709,6 +741,9 @@
1972 cap_set_full(bprm->cap_effective);
1973 }
1974
1975+ if (gr_handle_ptrace_exec(bprm->file->f_dentry, bprm->file->f_vfsmnt))
1976+ return -EACCES;
1977+
1978 memset(bprm->buf,0,BINPRM_BUF_SIZE);
1979 return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
1980 }
1981@@ -774,6 +809,8 @@
1982 current->suid = current->euid = current->fsuid = bprm->e_uid;
1983 current->sgid = current->egid = current->fsgid = bprm->e_gid;
1984
1985+ gr_handle_chroot_caps(current);
1986+
1987 if(do_unlock)
1988 unlock_kernel();
1989 current->keep_capabilities = 0;
1990@@ -907,6 +944,11 @@
1991 struct file *file;
1992 int retval;
1993 int i;
1994+#ifdef CONFIG_GRKERNSEC
1995+ struct file *old_exec_file;
1996+ struct acl_subject_label *old_acl;
1997+ struct rlimit old_rlim[RLIM_NLIMITS];
1998+#endif
1999
2000 file = open_exec(filename);
2001
2002@@ -914,6 +956,20 @@
2003 if (IS_ERR(file))
2004 return retval;
2005
2006+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes));
2007+
2008+ if (gr_handle_nproc()) {
2009+ allow_write_access(file);
2010+ fput(file);
2011+ return -EAGAIN;
2012+ }
2013+
2014+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
2015+ allow_write_access(file);
2016+ fput(file);
2017+ return -EACCES;
2018+ }
2019+
2020 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
2021 memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
2022
2023@@ -938,11 +999,26 @@
2024 if (retval < 0)
2025 goto out;
2026
2027+ if (!gr_tpe_allow(file)) {
2028+ retval = -EACCES;
2029+ goto out;
2030+ }
2031+
2032+ if(gr_check_crash_exec(file)) {
2033+ retval = -EACCES;
2034+ goto out;
2035+ }
2036+
2037 retval = copy_strings_kernel(1, &bprm.filename, &bprm);
2038 if (retval < 0)
2039 goto out;
2040
2041 bprm.exec = bprm.p;
2042+
2043+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
2044+
2045+ gr_handle_exec_args(&bprm, argv);
2046+
2047 retval = copy_strings(bprm.envc, envp, &bprm);
2048 if (retval < 0)
2049 goto out;
2050@@ -951,11 +1027,32 @@
2051 if (retval < 0)
2052 goto out;
2053
2054+#ifdef CONFIG_GRKERNSEC
2055+ old_acl = current->acl;
2056+ memcpy(old_rlim, current->rlim, sizeof(old_rlim));
2057+ old_exec_file = current->exec_file;
2058+ get_file(file);
2059+ current->exec_file = file;
2060+#endif
2061+
2062+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
2063+
2064 retval = search_binary_handler(&bprm,regs);
2065- if (retval >= 0)
2066+ if (retval >= 0) {
2067+#ifdef CONFIG_GRKERNSEC
2068+ if (old_exec_file)
2069+ fput(old_exec_file);
2070+#endif
2071 /* execve success */
2072 return retval;
2073+ }
2074
2075+#ifdef CONFIG_GRKERNSEC
2076+ current->acl = old_acl;
2077+ memcpy(current->rlim, old_rlim, sizeof(old_rlim));
2078+ fput(current->exec_file);
2079+ current->exec_file = old_exec_file;
2080+#endif
2081 out:
2082 /* Something went wrong, return the inode and free the argument pages*/
2083 allow_write_access(bprm.file);
2084@@ -1112,6 +1246,7 @@
2085 if (!is_dumpable(current))
2086 goto fail;
2087 current->mm->dumpable = 0;
2088+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump);
2089 if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
2090 goto fail;
2091
2092@@ -1131,7 +1266,7 @@
2093 goto close_fail;
2094 if (!file->f_op->write)
2095 goto close_fail;
2096- if (do_truncate(file->f_dentry, 0) != 0)
2097+ if (do_truncate(file->f_dentry, 0, file->f_vfsmnt) != 0)
2098 goto close_fail;
2099
2100 retval = binfmt->core_dump(signr, regs, file);
2101diff -urN linux-2.4.22/fs/fcntl.c linux-2.4.22/fs/fcntl.c
2102--- linux-2.4.22/fs/fcntl.c 2003-09-01 22:19:00.000000000 -0400
2103+++ linux-2.4.22/fs/fcntl.c 2003-09-02 19:29:42.000000000 -0400
2104@@ -11,6 +11,7 @@
2105 #include <linux/smp_lock.h>
2106 #include <linux/slab.h>
2107 #include <linux/iobuf.h>
2108+#include <linux/grsecurity.h>
2109
2110 #include <asm/poll.h>
2111 #include <asm/siginfo.h>
2112@@ -64,6 +65,8 @@
2113 int error;
2114 int start;
2115
2116+ gr_learn_resource(current, RLIMIT_NOFILE, orig_start);
2117+
2118 write_lock(&files->file_lock);
2119
2120 error = -EINVAL;
2121@@ -86,6 +89,7 @@
2122 }
2123
2124 error = -EMFILE;
2125+ gr_learn_resource(current, RLIMIT_NOFILE, newfd);
2126 if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
2127 goto out;
2128
2129@@ -141,6 +145,8 @@
2130 struct file * file, *tofree;
2131 struct files_struct * files = current->files;
2132
2133+ gr_learn_resource(current, RLIMIT_NOFILE, newfd);
2134+
2135 write_lock(&files->file_lock);
2136 if (!(file = fcheck(oldfd)))
2137 goto out_unlock;
2138@@ -448,6 +454,10 @@
2139 match = -p->pgrp;
2140 if (pid != match)
2141 continue;
2142+ if (gr_check_protected_task(p))
2143+ continue;
2144+ if (gr_pid_is_chrooted(p))
2145+ continue;
2146 send_sigio_to_task(p, fown, fd, band);
2147 }
2148 out:
2149diff -urN linux-2.4.22/fs/locks.c linux-2.4.22/fs/locks.c
2150--- linux-2.4.22/fs/locks.c 2003-09-01 22:19:00.000000000 -0400
2151+++ linux-2.4.22/fs/locks.c 2003-09-02 19:29:42.000000000 -0400
2152@@ -138,6 +138,7 @@
2153 static struct file_lock *locks_alloc_lock(int account)
2154 {
2155 struct file_lock *fl;
2156+ if(account) gr_learn_resource(current, RLIMIT_LOCKS, current->locks);
2157 if (account && current->locks >= current->rlim[RLIMIT_LOCKS].rlim_cur)
2158 return NULL;
2159 fl = kmem_cache_alloc(filelock_cache, SLAB_KERNEL);
2160diff -urN linux-2.4.22/fs/namei.c linux-2.4.22/fs/namei.c
2161--- linux-2.4.22/fs/namei.c 2003-09-01 22:19:00.000000000 -0400
2162+++ linux-2.4.22/fs/namei.c 2003-09-02 19:29:42.000000000 -0400
2163@@ -22,6 +22,7 @@
2164 #include <linux/dnotify.h>
2165 #include <linux/smp_lock.h>
2166 #include <linux/personality.h>
2167+#include <linux/grsecurity.h>
2168
2169 #include <asm/namei.h>
2170 #include <asm/uaccess.h>
2171@@ -343,6 +344,13 @@
2172 current->state = TASK_RUNNING;
2173 schedule();
2174 }
2175+
2176+ if (gr_handle_follow_link(dentry->d_parent->d_inode,
2177+ dentry->d_inode, dentry, nd->mnt)) {
2178+ path_release(nd);
2179+ return -EACCES;
2180+ }
2181+
2182 current->link_count++;
2183 current->total_link_count++;
2184 UPDATE_ATIME(dentry->d_inode);
2185@@ -643,6 +651,10 @@
2186 }
2187 }
2188 return_base:
2189+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
2190+ path_release(nd);
2191+ return -ENOENT;
2192+ }
2193 return 0;
2194 out_dput:
2195 dput(dentry);
2196@@ -1005,7 +1017,7 @@
2197 struct dentry *dentry;
2198 struct dentry *dir;
2199 int count = 0;
2200-
2201+
2202 acc_mode = ACC_MODE(flag);
2203
2204 /*
2205@@ -1015,7 +1027,19 @@
2206 error = path_lookup(pathname, lookup_flags(flag), nd);
2207 if (error)
2208 return error;
2209+
2210+ if (gr_handle_rawio(nd->dentry->d_inode)) {
2211+ error = -EPERM;
2212+ goto exit;
2213+ }
2214+
2215+ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
2216+ error = -EACCES;
2217+ goto exit;
2218+ }
2219+
2220 dentry = nd->dentry;
2221+
2222 goto ok;
2223 }
2224
2225@@ -1048,7 +1072,16 @@
2226 if (!dentry->d_inode) {
2227 if (!IS_POSIXACL(dir->d_inode))
2228 mode &= ~current->fs->umask;
2229+ if (!gr_acl_handle_creat(dentry, nd->dentry, nd->mnt, flag, mode)) {
2230+ error = -EACCES;
2231+ up(&dir->d_inode->i_sem);
2232+ goto exit_dput;
2233+ }
2234+
2235 error = vfs_create(dir->d_inode, dentry, mode);
2236+ if (!error)
2237+ gr_handle_create(dentry, nd->mnt);
2238+
2239 up(&dir->d_inode->i_sem);
2240 dput(nd->dentry);
2241 nd->dentry = dentry;
2242@@ -1058,12 +1091,35 @@
2243 /* Don't check for write permission, don't truncate */
2244 acc_mode = 0;
2245 flag &= ~O_TRUNC;
2246+
2247 goto ok;
2248 }
2249
2250 /*
2251 * It already exists.
2252 */
2253+
2254+ if (gr_acl_is_enabled() && S_ISBLK(dentry->d_inode->i_mode) &&
2255+ !capable(CAP_SYS_RAWIO)) {
2256+ error = -EPERM;
2257+ up(&dir->d_inode->i_sem);
2258+ goto exit_dput;
2259+ }
2260+
2261+ if (!gr_acl_handle_open(dentry, nd->mnt, flag)) {
2262+ error = -EACCES;
2263+ up(&dir->d_inode->i_sem);
2264+ goto exit_dput;
2265+ }
2266+
2267+ inode = dentry->d_inode;
2268+
2269+ if (gr_handle_fifo(dentry, nd->mnt, dir, flag, acc_mode)) {
2270+ up(&dir->d_inode->i_sem);
2271+ error = -EACCES;
2272+ goto exit_dput;
2273+ }
2274+
2275 up(&dir->d_inode->i_sem);
2276
2277 error = -EEXIST;
2278@@ -1153,7 +1209,7 @@
2279 if (!error) {
2280 DQUOT_INIT(inode);
2281
2282- error = do_truncate(dentry, 0);
2283+ error = do_truncate(dentry,0,nd->mnt);
2284 }
2285 put_write_access(inode);
2286 if (error)
2287@@ -1184,6 +1240,13 @@
2288 * stored in nd->last.name and we will have to putname() it when we
2289 * are done. Procfs-like symlinks just set LAST_BIND.
2290 */
2291+
2292+ if (gr_handle_follow_link(dentry->d_parent->d_inode, dentry->d_inode,
2293+ dentry, nd->mnt)) {
2294+ error = -EACCES;
2295+ goto exit_dput;
2296+ }
2297+
2298 UPDATE_ATIME(dentry->d_inode);
2299 error = dentry->d_inode->i_op->follow_link(dentry, nd);
2300 dput(dentry);
2301@@ -1282,6 +1345,18 @@
2302 if (!IS_POSIXACL(nd.dentry->d_inode))
2303 mode &= ~current->fs->umask;
2304 if (!IS_ERR(dentry)) {
2305+ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
2306+ error = -EPERM;
2307+ dput(dentry);
2308+ goto out_dput;
2309+ }
2310+
2311+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
2312+ error = -EACCES;
2313+ dput(dentry);
2314+ goto out_dput;
2315+ }
2316+
2317 switch (mode & S_IFMT) {
2318 case 0: case S_IFREG:
2319 error = vfs_create(nd.dentry->d_inode,dentry,mode);
2320@@ -1295,8 +1370,13 @@
2321 default:
2322 error = -EINVAL;
2323 }
2324+
2325+ if(!error)
2326+ gr_handle_create(dentry, nd.mnt);
2327+
2328 dput(dentry);
2329 }
2330+out_dput:
2331 up(&nd.dentry->d_inode->i_sem);
2332 path_release(&nd);
2333 out:
2334@@ -1348,7 +1428,16 @@
2335 if (!IS_ERR(dentry)) {
2336 if (!IS_POSIXACL(nd.dentry->d_inode))
2337 mode &= ~current->fs->umask;
2338- error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
2339+ error = 0;
2340+
2341+ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt))
2342+ error = -EACCES;
2343+
2344+ if(!error)
2345+ error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
2346+ if(!error)
2347+ gr_handle_create(dentry, nd.mnt);
2348+
2349 dput(dentry);
2350 }
2351 up(&nd.dentry->d_inode->i_sem);
2352@@ -1433,6 +1522,8 @@
2353 char * name;
2354 struct dentry *dentry;
2355 struct nameidata nd;
2356+ ino_t saved_ino = 0;
2357+ kdev_t saved_dev = 0;
2358
2359 name = getname(pathname);
2360 if(IS_ERR(name))
2361@@ -1457,7 +1548,22 @@
2362 dentry = lookup_hash(&nd.last, nd.dentry);
2363 error = PTR_ERR(dentry);
2364 if (!IS_ERR(dentry)) {
2365- error = vfs_rmdir(nd.dentry->d_inode, dentry);
2366+ error = 0;
2367+ if (dentry->d_inode) {
2368+ if (dentry->d_inode->i_nlink <= 1) {
2369+ saved_ino = dentry->d_inode->i_ino;
2370+ saved_dev = dentry->d_inode->i_dev;
2371+ }
2372+
2373+ if (!gr_acl_handle_rmdir(dentry, nd.mnt))
2374+ error = -EACCES;
2375+ }
2376+
2377+ if (!error)
2378+ error = vfs_rmdir(nd.dentry->d_inode, dentry);
2379+ if (!error && (saved_dev || saved_ino))
2380+ gr_handle_delete(saved_ino,saved_dev);
2381+
2382 dput(dentry);
2383 }
2384 up(&nd.dentry->d_inode->i_sem);
2385@@ -1501,6 +1607,8 @@
2386 char * name;
2387 struct dentry *dentry;
2388 struct nameidata nd;
2389+ ino_t saved_ino = 0;
2390+ kdev_t saved_dev = 0;
2391
2392 name = getname(pathname);
2393 if(IS_ERR(name))
2394@@ -1519,7 +1627,21 @@
2395 /* Why not before? Because we want correct error value */
2396 if (nd.last.name[nd.last.len])
2397 goto slashes;
2398- error = vfs_unlink(nd.dentry->d_inode, dentry);
2399+ error = 0;
2400+ if (dentry->d_inode) {
2401+ if (dentry->d_inode->i_nlink <= 1) {
2402+ saved_ino = dentry->d_inode->i_ino;
2403+ saved_dev = dentry->d_inode->i_dev;
2404+ }
2405+
2406+ if (!gr_acl_handle_unlink(dentry, nd.mnt))
2407+ error = -EACCES;
2408+ }
2409+
2410+ if (!error)
2411+ error = vfs_unlink(nd.dentry->d_inode, dentry);
2412+ if (!error && (saved_ino || saved_dev))
2413+ gr_handle_delete(saved_ino,saved_dev);
2414 exit2:
2415 dput(dentry);
2416 }
2417@@ -1583,7 +1705,15 @@
2418 dentry = lookup_create(&nd, 0);
2419 error = PTR_ERR(dentry);
2420 if (!IS_ERR(dentry)) {
2421- error = vfs_symlink(nd.dentry->d_inode, dentry, from);
2422+ error = 0;
2423+
2424+ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from))
2425+ error = -EACCES;
2426+
2427+ if(!error)
2428+ error = vfs_symlink(nd.dentry->d_inode, dentry, from);
2429+ if (!error)
2430+ gr_handle_create(dentry, nd.mnt);
2431 dput(dentry);
2432 }
2433 up(&nd.dentry->d_inode->i_sem);
2434@@ -1667,7 +1797,27 @@
2435 new_dentry = lookup_create(&nd, 0);
2436 error = PTR_ERR(new_dentry);
2437 if (!IS_ERR(new_dentry)) {
2438- error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
2439+ error = 0;
2440+
2441+ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
2442+ old_nd.dentry->d_inode,
2443+ old_nd.dentry->d_inode->i_mode, to)) {
2444+ error = -EPERM;
2445+ goto out_error;
2446+ }
2447+
2448+ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
2449+ old_nd.dentry, old_nd.mnt, to)) {
2450+ error = -EACCES;
2451+ goto out_error;
2452+ }
2453+
2454+ error = vfs_link(old_nd.dentry,
2455+ nd.dentry->d_inode, new_dentry);
2456+
2457+ if (!error)
2458+ gr_handle_create(new_dentry, nd.mnt);
2459+out_error:
2460 dput(new_dentry);
2461 }
2462 up(&nd.dentry->d_inode->i_sem);
2463@@ -1898,10 +2048,15 @@
2464 if (IS_ERR(new_dentry))
2465 goto exit4;
2466
2467- lock_kernel();
2468- error = vfs_rename(old_dir->d_inode, old_dentry,
2469+ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
2470+ old_dentry, old_dir->d_inode, oldnd.mnt, newname);
2471+
2472+ if (error == 1) {
2473+ lock_kernel();
2474+ error = vfs_rename(old_dir->d_inode, old_dentry,
2475 new_dir->d_inode, new_dentry);
2476- unlock_kernel();
2477+ unlock_kernel();
2478+ }
2479
2480 dput(new_dentry);
2481 exit4:
2482diff -urN linux-2.4.22/fs/namespace.c linux-2.4.22/fs/namespace.c
2483--- linux-2.4.22/fs/namespace.c 2003-09-01 22:19:00.000000000 -0400
2484+++ linux-2.4.22/fs/namespace.c 2003-09-02 19:29:42.000000000 -0400
2485@@ -15,6 +15,8 @@
2486 #include <linux/quotaops.h>
2487 #include <linux/acct.h>
2488 #include <linux/module.h>
2489+#include <linux/sched.h>
2490+#include <linux/grsecurity.h>
2491
2492 #include <asm/uaccess.h>
2493
2494@@ -325,6 +327,8 @@
2495 lock_kernel();
2496 retval = do_remount_sb(sb, MS_RDONLY, 0);
2497 unlock_kernel();
2498+
2499+ gr_log_remount(mnt->mnt_devname, retval);
2500 }
2501 up_write(&sb->s_umount);
2502 return retval;
2503@@ -350,6 +354,9 @@
2504 }
2505 spin_unlock(&dcache_lock);
2506 up_write(&current->namespace->sem);
2507+
2508+ gr_log_unmount(mnt->mnt_devname, retval);
2509+
2510 return retval;
2511 }
2512
2513@@ -729,6 +736,12 @@
2514 if (retval)
2515 return retval;
2516
2517+ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
2518+ retval = -EPERM;
2519+ path_release(&nd);
2520+ return retval;
2521+ }
2522+
2523 if (flags & MS_REMOUNT)
2524 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
2525 data_page);
2526@@ -740,6 +753,9 @@
2527 retval = do_add_mount(&nd, type_page, flags, mnt_flags,
2528 dev_name, data_page);
2529 path_release(&nd);
2530+
2531+ gr_log_mount(dev_name, dir_name, retval);
2532+
2533 return retval;
2534 }
2535
2536@@ -909,6 +925,9 @@
2537 if (!capable(CAP_SYS_ADMIN))
2538 return -EPERM;
2539
2540+ if (gr_handle_chroot_pivot())
2541+ return -EPERM;
2542+
2543 lock_kernel();
2544
2545 error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
2546diff -urN linux-2.4.22/fs/open.c linux-2.4.22/fs/open.c
2547--- linux-2.4.22/fs/open.c 2003-09-01 22:19:00.000000000 -0400
2548+++ linux-2.4.22/fs/open.c 2003-09-02 19:29:42.000000000 -0400
2549@@ -15,6 +15,7 @@
2550 #include <linux/slab.h>
2551 #include <linux/tty.h>
2552 #include <linux/iobuf.h>
2553+#include <linux/grsecurity.h>
2554
2555 #include <asm/uaccess.h>
2556
2557@@ -95,7 +96,7 @@
2558 write_unlock(&files->file_lock);
2559 }
2560
2561-int do_truncate(struct dentry *dentry, loff_t length)
2562+int do_truncate(struct dentry *dentry, loff_t length, struct vfsmount *mnt)
2563 {
2564 struct inode *inode = dentry->d_inode;
2565 int error;
2566@@ -105,6 +106,9 @@
2567 if (length < 0)
2568 return -EINVAL;
2569
2570+ if (!gr_acl_handle_truncate(dentry, mnt))
2571+ return -EACCES;
2572+
2573 down_write(&inode->i_alloc_sem);
2574 down(&inode->i_sem);
2575 newattrs.ia_size = length;
2576@@ -165,7 +169,7 @@
2577 error = locks_verify_truncate(inode, NULL, length);
2578 if (!error) {
2579 DQUOT_INIT(inode);
2580- error = do_truncate(nd.dentry, length);
2581+ error = do_truncate(nd.dentry, length, nd.mnt);
2582 }
2583 put_write_access(inode);
2584
2585@@ -217,7 +221,7 @@
2586
2587 error = locks_verify_truncate(inode, file, length);
2588 if (!error)
2589- error = do_truncate(dentry, length);
2590+ error = do_truncate(dentry, length, file->f_vfsmnt);
2591 out_putf:
2592 fput(file);
2593 out:
2594@@ -286,6 +290,12 @@
2595 (error = permission(inode,MAY_WRITE)) != 0)
2596 goto dput_and_out;
2597 }
2598+
2599+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
2600+ error = -EACCES;
2601+ goto dput_and_out;
2602+ }
2603+
2604 error = notify_change(nd.dentry, &newattrs);
2605 dput_and_out:
2606 path_release(&nd);
2607@@ -331,6 +341,12 @@
2608 (error = permission(inode,MAY_WRITE)) != 0)
2609 goto dput_and_out;
2610 }
2611+
2612+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
2613+ error = -EACCES;
2614+ goto dput_and_out;
2615+ }
2616+
2617 error = notify_change(nd.dentry, &newattrs);
2618 dput_and_out:
2619 path_release(&nd);
2620@@ -373,6 +389,10 @@
2621 if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
2622 && !special_file(nd.dentry->d_inode->i_mode))
2623 res = -EROFS;
2624+
2625+ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
2626+ res = -EACCES;
2627+
2628 path_release(&nd);
2629 }
2630
2631@@ -396,6 +416,8 @@
2632 if (error)
2633 goto dput_and_out;
2634
2635+ gr_log_chdir(nd.dentry, nd.mnt);
2636+
2637 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
2638
2639 dput_and_out:
2640@@ -426,6 +448,13 @@
2641 goto out_putf;
2642
2643 error = permission(inode, MAY_EXEC);
2644+
2645+ if (!error && !gr_chroot_fchdir(dentry, mnt))
2646+ error = -EPERM;
2647+
2648+ if (!error)
2649+ gr_log_chdir(dentry, mnt);
2650+
2651 if (!error)
2652 set_fs_pwd(current->fs, mnt, dentry);
2653 out_putf:
2654@@ -452,8 +481,16 @@
2655 if (!capable(CAP_SYS_CHROOT))
2656 goto dput_and_out;
2657
2658+ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
2659+ goto dput_and_out;
2660+
2661 set_fs_root(current->fs, nd.mnt, nd.dentry);
2662 set_fs_altroot();
2663+
2664+ gr_handle_chroot_caps(current);
2665+
2666+ gr_handle_chroot_chdir(nd.dentry, nd.mnt);
2667+
2668 error = 0;
2669 dput_and_out:
2670 path_release(&nd);
2671@@ -482,8 +519,20 @@
2672 err = -EPERM;
2673 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
2674 goto out_putf;
2675+
2676+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
2677+ err = -EACCES;
2678+ goto out_putf;
2679+ }
2680+
2681 if (mode == (mode_t) -1)
2682 mode = inode->i_mode;
2683+
2684+ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
2685+ err = -EPERM;
2686+ goto out_putf;
2687+ }
2688+
2689 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
2690 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
2691 err = notify_change(dentry, &newattrs);
2692@@ -514,8 +563,19 @@
2693 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
2694 goto dput_and_out;
2695
2696+ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
2697+ error = -EACCES;
2698+ goto dput_and_out;
2699+ }
2700+
2701 if (mode == (mode_t) -1)
2702 mode = inode->i_mode;
2703+
2704+ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
2705+ error = -EACCES;
2706+ goto dput_and_out;
2707+ }
2708+
2709 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
2710 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
2711 error = notify_change(nd.dentry, &newattrs);
2712@@ -526,7 +586,7 @@
2713 return error;
2714 }
2715
2716-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
2717+static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
2718 {
2719 struct inode * inode;
2720 int error;
2721@@ -543,6 +603,12 @@
2722 error = -EPERM;
2723 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
2724 goto out;
2725+
2726+ if (!gr_acl_handle_chown(dentry, mnt)) {
2727+ error = -EACCES;
2728+ goto out;
2729+ }
2730+
2731 if (user == (uid_t) -1)
2732 user = inode->i_uid;
2733 if (group == (gid_t) -1)
2734@@ -593,7 +659,7 @@
2735
2736 error = user_path_walk(filename, &nd);
2737 if (!error) {
2738- error = chown_common(nd.dentry, user, group);
2739+ error = chown_common(nd.dentry, user, group, nd.mnt);
2740 path_release(&nd);
2741 }
2742 return error;
2743@@ -606,7 +672,7 @@
2744
2745 error = user_path_walk_link(filename, &nd);
2746 if (!error) {
2747- error = chown_common(nd.dentry, user, group);
2748+ error = chown_common(nd.dentry, user, group, nd.mnt);
2749 path_release(&nd);
2750 }
2751 return error;
2752@@ -620,7 +686,8 @@
2753
2754 file = fget(fd);
2755 if (file) {
2756- error = chown_common(file->f_dentry, user, group);
2757+ error = chown_common(file->f_dentry, user,
2758+ group, file->f_vfsmnt);
2759 fput(file);
2760 }
2761 return error;
2762@@ -740,6 +807,7 @@
2763 * N.B. For clone tasks sharing a files structure, this test
2764 * will limit the total number of files that can be opened.
2765 */
2766+ gr_learn_resource(current, RLIMIT_NOFILE, fd);
2767 if (fd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
2768 goto out;
2769
2770diff -urN linux-2.4.22/fs/proc/array.c linux-2.4.22/fs/proc/array.c
2771--- linux-2.4.22/fs/proc/array.c 2003-09-01 22:19:00.000000000 -0400
2772+++ linux-2.4.22/fs/proc/array.c 2003-09-02 19:29:42.000000000 -0400
2773@@ -334,6 +340,12 @@
2774
2775 wchan = get_wchan(task);
2776
2777+#ifdef CONFIG_GRKERNSEC_HIDESYM
2778+ wchan = 0;
2779+ eip = 0;
2780+ esp = 0;
2781+#endif
2782+
2783 collect_sigign_sigcatch(task, &sigign, &sigcatch);
2784
2785 /* scale priority and nice values from timeslices to -20..20 */
2786@@ -684,6 +728,16 @@
2787 return retval;
2788 }
2789
2790+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
2791+int proc_pid_ipaddr(struct task_struct *task, char * buffer)
2792+{
2793+ int len;
2794+
2795+ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->curr_ip));
2796+ return len;
2797+}
2798+#endif
2799+
2800 #ifdef CONFIG_SMP
2801 int proc_pid_cpu(struct task_struct *task, char * buffer)
2802 {
2803diff -urN linux-2.4.22/fs/proc/base.c linux-2.4.22/fs/proc/base.c
2804--- linux-2.4.22/fs/proc/base.c 2003-09-01 22:19:00.000000000 -0400
2805+++ linux-2.4.22/fs/proc/base.c 2003-09-02 19:29:42.000000000 -0400
2806@@ -25,6 +25,7 @@
2807 #include <linux/string.h>
2808 #include <linux/seq_file.h>
2809 #include <linux/namespace.h>
2810+#include <linux/grsecurity.h>
2811
2812 /*
2813 * For hysterical raisins we keep the same inumbers as in the old procfs.
2814@@ -41,6 +42,9 @@
2815 int proc_pid_status(struct task_struct*,char*);
2816 int proc_pid_statm(struct task_struct*,char*);
2817 int proc_pid_cpu(struct task_struct*,char*);
2818+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
2819+int proc_pid_ipaddr(struct task_struct*,char*);
2820+#endif
2821
2822 static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
2823 {
2824@@ -264,9 +268,22 @@
2825
2826 static int proc_permission(struct inode *inode, int mask)
2827 {
2828+ int ret;
2829+ struct task_struct *task;
2830+
2831 if (vfs_permission(inode, mask) != 0)
2832 return -EACCES;
2833- return proc_check_root(inode);
2834+ ret = proc_check_root(inode);
2835+
2836+ if (ret)
2837+ return ret;
2838+
2839+ task = inode->u.proc_i.task;
2840+
2841+ if (!task)
2842+ return 0;
2843+
2844+ return gr_acl_handle_procpidmem(task);
2845 }
2846
2847 static ssize_t pid_maps_read(struct file * file, char * buf,
2848@@ -576,6 +593,9 @@
2849 PROC_PID_STATM,
2850 PROC_PID_MAPS,
2851 PROC_PID_CPU,
2852+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
2853+ PROC_PID_IPADDR,
2854+#endif
2855 PROC_PID_MOUNTS,
2856 PROC_PID_FD_DIR = 0x8000, /* 0x8000-0xffff */
2857 };
2858@@ -591,6 +611,9 @@
2859 #ifdef CONFIG_SMP
2860 E(PROC_PID_CPU, "cpu", S_IFREG|S_IRUGO),
2861 #endif
2862+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
2863+ E(PROC_PID_IPADDR, "ipaddr", S_IFREG|S_IRUSR),
2864+#endif
2865 E(PROC_PID_MAPS, "maps", S_IFREG|S_IRUGO),
2866 E(PROC_PID_MEM, "mem", S_IFREG|S_IRUSR|S_IWUSR),
2867 E(PROC_PID_CWD, "cwd", S_IFLNK|S_IRWXUGO),
2868@@ -747,10 +770,17 @@
2869 get_task_struct(task);
2870 inode->u.proc_i.task = task;
2871 inode->i_uid = 0;
2872+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
2873+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
2874+#else
2875 inode->i_gid = 0;
2876+#endif
2877+
2878 if (ino == PROC_PID_INO || task_dumpable(task)) {
2879 inode->i_uid = task->euid;
2880+#ifndef CONFIG_GRKERNSEC_PROC_USERGROUP
2881 inode->i_gid = task->egid;
2882+#endif
2883 }
2884
2885 out:
2886@@ -958,6 +988,12 @@
2887 inode->u.proc_i.op.proc_read = proc_pid_cpu;
2888 break;
2889 #endif
2890+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
2891+ case PROC_PID_IPADDR:
2892+ inode->i_fop = &proc_info_file_operations;
2893+ inode->u.proc_i.op.proc_read = proc_pid_ipaddr;
2894+ break;
2895+#endif
2896 case PROC_PID_MEM:
2897 inode->i_op = &proc_mem_inode_operations;
2898 inode->i_fop = &proc_mem_operations;
2899@@ -1056,13 +1092,34 @@
2900 if (!task)
2901 goto out;
2902
2903+ if(gr_check_hidden_task(task)) {
2904+ free_task_struct(task);
2905+ goto out;
2906+ }
2907+
2908+#ifdef CONFIG_GRKERNSEC_PROC
2909+ if (current->uid && (task->uid != current->uid)
2910+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
2911+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
2912+#endif
2913+ ) {
2914+ free_task_struct(task);
2915+ goto out;
2916+ }
2917+#endif
2918 inode = proc_pid_make_inode(dir->i_sb, task, PROC_PID_INO);
2919
2920 free_task_struct(task);
2921
2922 if (!inode)
2923 goto out;
2924+#ifdef CONFIG_GRKERNSEC_PROC_USER
2925+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
2926+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
2927+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP;
2928+#else
2929 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
2930+#endif
2931 inode->i_op = &proc_base_inode_operations;
2932 inode->i_fop = &proc_base_operations;
2933 inode->i_nlink = 3;
2934@@ -1102,6 +1159,18 @@
2935 int pid = p->pid;
2936 if (!pid)
2937 continue;
2938+ if(gr_pid_is_chrooted(p))
2939+ continue;
2940+ if(gr_check_hidden_task(p))
2941+ continue;
2942+#ifdef CONFIG_GRKERNSEC_PROC
2943+ if (current->uid && (p->uid != current->uid)
2944+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
2945+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
2946+#endif
2947+ )
2948+ continue;
2949+#endif
2950 if (--index >= 0)
2951 continue;
2952 pids[nr_pids] = pid;
2953diff -urN linux-2.4.22/fs/proc/generic.c linux-2.4.22/fs/proc/generic.c
2954--- linux-2.4.22/fs/proc/generic.c 2003-09-01 22:19:00.000000000 -0400
2955+++ linux-2.4.22/fs/proc/generic.c 2003-09-02 19:29:42.000000000 -0400
2956@@ -503,6 +503,32 @@
2957 return ent;
2958 }
2959
2960+#ifdef CONFIG_GRKERNSEC_PROC
2961+struct proc_dir_entry *proc_priv_mkdir(const char *name, struct proc_dir_entry *parent)
2962+{
2963+ struct proc_dir_entry *ent;
2964+ mode_t mode = 0;
2965+
2966+#ifdef CONFIG_GRKERNSEC_PROC_USER
2967+ mode = S_IFDIR | S_IRUSR | S_IXUSR;
2968+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
2969+ mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP;
2970+#endif
2971+
2972+ ent = proc_create(&parent, name, mode, 2);
2973+ if (ent) {
2974+ ent->proc_fops = &proc_dir_operations;
2975+ ent->proc_iops = &proc_dir_inode_operations;
2976+
2977+ if (proc_register(parent, ent) < 0) {
2978+ kfree(ent);
2979+ ent = NULL;
2980+ }
2981+ }
2982+ return ent;
2983+}
2984+#endif
2985+
2986 struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
2987 struct proc_dir_entry *parent)
2988 {
2989diff -urN linux-2.4.22/fs/proc/inode.c linux-2.4.22/fs/proc/inode.c
2990--- linux-2.4.22/fs/proc/inode.c 2003-09-01 22:19:00.000000000 -0400
2991+++ linux-2.4.22/fs/proc/inode.c 2003-09-02 19:29:42.000000000 -0400
2992@@ -152,7 +152,11 @@
2993 if (de->mode) {
2994 inode->i_mode = de->mode;
2995 inode->i_uid = de->uid;
2996+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
2997+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
2998+#else
2999 inode->i_gid = de->gid;
3000+#endif
3001 }
3002 if (de->size)
3003 inode->i_size = de->size;
3004diff -urN linux-2.4.22/fs/proc/proc_misc.c linux-2.4.22/fs/proc/proc_misc.c
3005--- linux-2.4.22/fs/proc/proc_misc.c 2003-09-01 22:19:00.000000000 -0400
3006+++ linux-2.4.22/fs/proc/proc_misc.c 2003-09-02 19:29:42.000000000 -0400
3007@@ -569,6 +569,7 @@
3008 void __init proc_misc_init(void)
3009 {
3010 struct proc_dir_entry *entry;
3011+ int gr_mode = 0;
3012 static struct {
3013 char *name;
3014 int (*read_proc)(char*,char**,off_t,int,int*,void*);
3015@@ -583,48 +584,81 @@
3016 #ifdef CONFIG_STRAM_PROC
3017 {"stram", stram_read_proc},
3018 #endif
3019-#ifdef CONFIG_MODULES
3020+#if defined(CONFIG_MODULES) && !defined(CONFIG_GRKERNSEC_PROC)
3021 {"modules", modules_read_proc},
3022 #endif
3023 {"stat", kstat_read_proc},
3024+#ifndef CONFIG_GRKERNSEC_PROC_ADD
3025 {"devices", devices_read_proc},
3026-#if !defined(CONFIG_ARCH_S390)
3027+#endif
3028+#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
3029 {"interrupts", interrupts_read_proc},
3030 #endif
3031 {"filesystems", filesystems_read_proc},
3032+#ifndef CONFIG_GRKERNSEC_PROC_ADD
3033 {"dma", dma_read_proc},
3034 {"ioports", ioports_read_proc},
3035 {"cmdline", cmdline_read_proc},
3036+#endif
3037 #ifdef CONFIG_SGI_DS1286
3038 {"rtc", ds1286_read_proc},
3039 #endif
3040 {"locks", locks_read_proc},
3041 {"swaps", swaps_read_proc},
3042+#ifndef CONFIG_GRKERNSEC_PROC_ADD
3043 {"iomem", memory_read_proc},
3044+#endif
3045 {"execdomains", execdomains_read_proc},
3046 {NULL,}
3047 };
3048 for (p = simple_ones; p->name; p++)
3049 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
3050
3051+#ifdef CONFIG_GRKERNSEC_PROC_USER
3052+ gr_mode = S_IRUSR;
3053+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
3054+ gr_mode = S_IRUSR | S_IRGRP;
3055+#endif
3056+
3057+#if defined(CONFIG_GRKERNSEC_PROC) && defined(CONFIG_MODULES)
3058+ create_proc_read_entry("modules", gr_mode, NULL, &modules_read_proc, NULL);
3059+#endif
3060+#ifdef CONFIG_GRKERNSEC_PROC_ADD
3061+ create_proc_read_entry("devices", gr_mode, NULL, &devices_read_proc, NULL);
3062+ create_proc_read_entry("dma", gr_mode, NULL, &dma_read_proc, NULL);
3063+ create_proc_read_entry("ioports", gr_mode, NULL, &ioports_read_proc, NULL);
3064+ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
3065+ create_proc_read_entry("iomem", gr_mode, NULL, &memory_read_proc, NULL);
3066+#if !defined(CONFIG_ARCH_S390)
3067+ create_proc_read_entry("interrupts", gr_mode, NULL, &interrupts_read_proc, NULL);
3068+#endif
3069+#endif
3070+
3071 proc_symlink("mounts", NULL, "self/mounts");
3072
3073 /* And now for trickier ones */
3074 entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
3075 if (entry)
3076 entry->proc_fops = &proc_kmsg_operations;
3077+#ifdef CONFIG_GRKERNSEC_PROC_ADD
3078+ create_seq_entry("cpuinfo", gr_mode, &proc_cpuinfo_operations);
3079+ create_seq_entry("slabinfo", gr_mode,&proc_slabinfo_operations);
3080+#else
3081 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
3082- create_seq_entry("partitions", 0, &proc_partitions_operations);
3083 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
3084+#endif
3085+ create_seq_entry("partitions", 0, &proc_partitions_operations);
3086 #ifdef CONFIG_MODULES
3087- create_seq_entry("ksyms", 0, &proc_ksyms_operations);
3088+ create_seq_entry("ksyms", gr_mode, &proc_ksyms_operations);
3089 #endif
3090+#ifndef CONFIG_GRKERNSEC_PROC_ADD
3091 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
3092 if (proc_root_kcore) {
3093 proc_root_kcore->proc_fops = &proc_kcore_operations;
3094 proc_root_kcore->size =
3095 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
3096 }
3097+#endif
3098 if (prof_shift) {
3099 entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
3100 if (entry) {
3101diff -urN linux-2.4.22/fs/proc/root.c linux-2.4.22/fs/proc/root.c
3102--- linux-2.4.22/fs/proc/root.c 2003-09-01 22:19:00.000000000 -0400
3103+++ linux-2.4.22/fs/proc/root.c 2003-09-02 19:29:42.000000000 -0400
3104@@ -37,13 +37,21 @@
3105 return;
3106 }
3107 proc_misc_init();
3108+#ifdef CONFIG_GRKERNSEC_PROC
3109+ proc_net = proc_priv_mkdir("net", 0);
3110+#else
3111 proc_net = proc_mkdir("net", 0);
3112+#endif
3113 #ifdef CONFIG_SYSVIPC
3114 proc_mkdir("sysvipc", 0);
3115 #endif
3116 #ifdef CONFIG_SYSCTL
3117+#ifdef CONFIG_GRKERNSEC_PROC
3118+ proc_sys_root = proc_priv_mkdir("sys", 0);
3119+#else
3120 proc_sys_root = proc_mkdir("sys", 0);
3121 #endif
3122+#endif
3123 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
3124 proc_mkdir("sys/fs", 0);
3125 proc_mkdir("sys/fs/binfmt_misc", 0);
3126@@ -67,7 +75,12 @@
3127 #ifdef CONFIG_PPC_RTAS
3128 proc_rtas_init();
3129 #endif
3130+
3131+#ifdef CONFIG_GRKERNSEC_PROC_ADD
3132+ proc_bus = proc_priv_mkdir("bus", 0);
3133+#else
3134 proc_bus = proc_mkdir("bus", 0);
3135+#endif
3136 }
3137
3138 static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
3139diff -urN linux-2.4.22/fs/readdir.c linux-2.4.22/fs/readdir.c
3140--- linux-2.4.22/fs/readdir.c 2003-09-01 22:19:00.000000000 -0400
3141+++ linux-2.4.22/fs/readdir.c 2003-09-02 19:29:42.000000000 -0400
3142@@ -10,6 +10,7 @@
3143 #include <linux/stat.h>
3144 #include <linux/file.h>
3145 #include <linux/smp_lock.h>
3146+#include <linux/grsecurity.h>
3147
3148 #include <asm/uaccess.h>
3149
3150@@ -181,6 +182,7 @@
3151 struct readdir_callback {
3152 struct old_linux_dirent * dirent;
3153 int count;
3154+ struct nameidata nd;
3155 };
3156
3157 static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
3158@@ -191,6 +193,10 @@
3159
3160 if (buf->count)
3161 return -EINVAL;
3162+
3163+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
3164+ return 0;
3165+
3166 buf->count++;
3167 dirent = buf->dirent;
3168 put_user(ino, &dirent->d_ino);
3169@@ -215,6 +221,9 @@
3170 buf.count = 0;
3171 buf.dirent = dirent;
3172
3173+ buf.nd.dentry = file->f_dentry;
3174+ buf.nd.mnt = file->f_vfsmnt;
3175+
3176 error = vfs_readdir(file, fillonedir, &buf);
3177 if (error >= 0)
3178 error = buf.count;
3179@@ -242,6 +251,7 @@
3180 struct linux_dirent * previous;
3181 int count;
3182 int error;
3183+ struct nameidata nd;
3184 };
3185
3186 static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
3187@@ -254,6 +264,10 @@
3188 buf->error = -EINVAL; /* only used if we fail.. */
3189 if (reclen > buf->count)
3190 return -EINVAL;
3191+
3192+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
3193+ return 0;
3194+
3195 dirent = buf->previous;
3196 if (dirent)
3197 put_user(offset, &dirent->d_off);
3198@@ -286,6 +300,9 @@
3199 buf.count = count;
3200 buf.error = 0;
3201
3202+ buf.nd.dentry = file->f_dentry;
3203+ buf.nd.mnt = file->f_vfsmnt;
3204+
3205 error = vfs_readdir(file, filldir, &buf);
3206 if (error < 0)
3207 goto out_putf;
3208@@ -320,6 +337,7 @@
3209 struct linux_dirent64 * previous;
3210 int count;
3211 int error;
3212+ struct nameidata nd;
3213 };
3214
3215 static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
3216@@ -332,6 +350,10 @@
3217 buf->error = -EINVAL; /* only used if we fail.. */
3218 if (reclen > buf->count)
3219 return -EINVAL;
3220+
3221+ if (!gr_acl_handle_filldir(buf->nd.dentry, buf->nd.mnt, ino))
3222+ return 0;
3223+
3224 dirent = buf->previous;
3225 if (dirent) {
3226 d.d_off = offset;
3227@@ -369,6 +391,9 @@
3228 buf.count = count;
3229 buf.error = 0;
3230
3231+ buf.nd.mnt = file->f_vfsmnt;
3232+ buf.nd.dentry = file->f_dentry;
3233+
3234 error = vfs_readdir(file, filldir64, &buf);
3235 if (error < 0)
3236 goto out_putf;
3237diff -urN linux-2.4.22/grsecurity/Config.in linux-2.4.22/grsecurity/Config.in
3238--- linux-2.4.22/grsecurity/Config.in 1969-12-31 19:00:00.000000000 -0500
3239+++ linux-2.4.22/grsecurity/Config.in 2003-09-02 19:29:42.000000000 -0400
3240@@ -0,0 +1,262 @@
3241+define_bool CONFIG_CRYPTO y
3242+define_bool CONFIG_CRYPTO_SHA256 y
3243+choice 'Security level' \
3244+ "Low CONFIG_GRKERNSEC_LOW \
3245+ Medium CONFIG_GRKERNSEC_MID \
3246+ High CONFIG_GRKERNSEC_HI \
3247+ Customized CONFIG_GRKERNSEC_CUSTOM" Customized
3248+if [ "$CONFIG_GRKERNSEC_LOW" = "y" ]; then
3249+define_bool CONFIG_GRKERNSEC_RANDSRC n
3250+define_bool CONFIG_GRKERNSEC_RANDRPC n
3251+define_bool CONFIG_GRKERNSEC_FORKFAIL n
3252+define_bool CONFIG_GRKERNSEC_TIME n
3253+define_bool CONFIG_GRKERNSEC_SIGNAL n
3254+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
3255+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT n
3256+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
3257+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE n
3258+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT n
3259+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD n
3260+define_bool CONFIG_GRKERNSEC_PROC n
3261+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
3262+define_bool CONFIG_GRKERNSEC_HIDESYM n
3263+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
3264+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL n
3265+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP n
3266+define_bool CONFIG_GRKERNSEC_KMEM n
3267+define_bool CONFIG_GRKERNSEC_PROC_ADD n
3268+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
3269+define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
3270+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
3271+if [ "$CONFIG_X86" = "y" ]; then
3272+define_bool CONFIG_GRKERNSEC_IO n
3273+fi
3274+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
3275+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
3276+define_bool CONFIG_GRKERNSEC_RESLOG n
3277+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
3278+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
3279+
3280+define_int CONFIG_GRKERNSEC_FLOODTIME 10
3281+define_int CONFIG_GRKERNSEC_FLOODBURST 4
3282+define_bool CONFIG_GRKERNSEC_LINK y
3283+define_bool CONFIG_GRKERNSEC_FIFO y
3284+define_bool CONFIG_GRKERNSEC_RANDPID y
3285+define_bool CONFIG_GRKERNSEC_EXECVE y
3286+define_bool CONFIG_GRKERNSEC_RANDNET y
3287+define_bool CONFIG_GRKERNSEC_RANDISN n
3288+define_bool CONFIG_GRKERNSEC_DMESG y
3289+define_bool CONFIG_GRKERNSEC_RANDID y
3290+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
3291+fi
3292+if [ "$CONFIG_GRKERNSEC_MID" = "y" ]; then
3293+define_bool CONFIG_GRKERNSEC_KMEM n
3294+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
3295+define_bool CONFIG_GRKERNSEC_HIDESYM n
3296+define_bool CONFIG_GRKERNSEC_PROC_ADD n
3297+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD n
3298+define_bool CONFIG_GRKERNSEC_CHROOT_NICE n
3299+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK n
3300+if [ "$CONFIG_X86" = "y" ]; then
3301+define_bool CONFIG_GRKERNSEC_IO n
3302+fi
3303+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
3304+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS n
3305+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
3306+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
3307+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR n
3308+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
3309+define_bool CONFIG_GRKERNSEC_RESLOG n
3310+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
3311+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
3312+
3313+define_int CONFIG_GRKERNSEC_FLOODTIME 10
3314+define_int CONFIG_GRKERNSEC_FLOODBURST 4
3315+define_bool CONFIG_GRKERNSEC_LINK y
3316+define_bool CONFIG_GRKERNSEC_FIFO y
3317+define_bool CONFIG_GRKERNSEC_RANDPID y
3318+define_bool CONFIG_GRKERNSEC_EXECVE y
3319+define_bool CONFIG_GRKERNSEC_DMESG y
3320+define_bool CONFIG_GRKERNSEC_RANDID y
3321+define_bool CONFIG_GRKERNSEC_RANDNET y
3322+define_bool CONFIG_GRKERNSEC_RANDISN y
3323+define_bool CONFIG_GRKERNSEC_RANDSRC y
3324+define_bool CONFIG_GRKERNSEC_RANDRPC y
3325+define_bool CONFIG_GRKERNSEC_FORKFAIL y
3326+define_bool CONFIG_GRKERNSEC_TIME y
3327+define_bool CONFIG_GRKERNSEC_SIGNAL y
3328+define_bool CONFIG_GRKERNSEC_CHROOT y
3329+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT n
3330+define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
3331+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
3332+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
3333+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
3334+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
3335+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
3336+define_bool CONFIG_GRKERNSEC_PROC y
3337+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
3338+define_int CONFIG_GRKERNSEC_PROC_GID 10
3339+fi
3340+if [ "$CONFIG_GRKERNSEC_HI" = "y" ]; then
3341+define_int CONFIG_GRKERNSEC_FLOODTIME 10
3342+define_int CONFIG_GRKERNSEC_FLOODBURST 4
3343+define_bool CONFIG_GRKERNSEC_LINK y
3344+define_bool CONFIG_GRKERNSEC_FIFO y
3345+define_bool CONFIG_GRKERNSEC_RANDPID y
3346+define_bool CONFIG_GRKERNSEC_EXECVE y
3347+define_bool CONFIG_GRKERNSEC_DMESG y
3348+define_bool CONFIG_GRKERNSEC_RANDID y
3349+define_bool CONFIG_GRKERNSEC_RANDSRC y
3350+define_bool CONFIG_GRKERNSEC_RANDRPC y
3351+define_bool CONFIG_GRKERNSEC_FORKFAIL y
3352+define_bool CONFIG_GRKERNSEC_TIME y
3353+define_bool CONFIG_GRKERNSEC_SIGNAL y
3354+define_bool CONFIG_GRKERNSEC_CHROOT_SHMAT y
3355+define_bool CONFIG_GRKERNSEC_CHROOT_UNIX y
3356+define_bool CONFIG_GRKERNSEC_CHROOT_MOUNT y
3357+define_bool CONFIG_GRKERNSEC_CHROOT_FCHDIR y
3358+define_bool CONFIG_GRKERNSEC_CHROOT_PIVOT y
3359+define_bool CONFIG_GRKERNSEC_CHROOT_DOUBLE y
3360+define_bool CONFIG_GRKERNSEC_CHROOT_CHDIR y
3361+define_bool CONFIG_GRKERNSEC_CHROOT_MKNOD y
3362+define_bool CONFIG_GRKERNSEC_CHROOT_CAPS y
3363+define_bool CONFIG_GRKERNSEC_CHROOT_SYSCTL y
3364+define_bool CONFIG_GRKERNSEC_CHROOT_FINDTASK y
3365+define_bool CONFIG_GRKERNSEC_PROC y
3366+define_bool CONFIG_GRKERNSEC_PROC_IPADDR n
3367+define_bool CONFIG_GRKERNSEC_HIDESYM y
3368+define_bool CONFIG_GRKERNSEC_PROC_USERGROUP y
3369+define_int CONFIG_GRKERNSEC_PROC_GID 10
3370+define_bool CONFIG_GRKERNSEC_KMEM y
3371+define_bool CONFIG_GRKERNSEC_RESLOG y
3372+define_bool CONFIG_GRKERNSEC_RANDNET y
3373+define_bool CONFIG_GRKERNSEC_RANDISN y
3374+
3375+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT n
3376+define_bool CONFIG_GRKERNSEC_ACL_HIDEKERN n
3377+define_int CONFIG_GRKERNSEC_ACL_MAXTRIES 3
3378+define_int CONFIG_GRKERNSEC_ACL_TIMEOUT 30
3379+
3380+define_bool CONFIG_GRKERNSEC_PROC_ADD y
3381+define_bool CONFIG_GRKERNSEC_CHROOT_CHMOD y
3382+define_bool CONFIG_GRKERNSEC_CHROOT_NICE y
3383+if [ "$CONFIG_X86" = "y" ]; then
3384+define_bool CONFIG_GRKERNSEC_IO n
3385+fi
3386+define_bool CONFIG_GRKERNSEC_AUDIT_MOUNT y
3387+fi
3388+if [ "$CONFIG_GRKERNSEC_CUSTOM" = "y" ]; then
3389+mainmenu_option next_comment
3390+comment 'Address Space Protection'
3391+bool 'Deny writing to /dev/kmem, /dev/mem, and /dev/port' CONFIG_GRKERNSEC_KMEM
3392+if [ "$CONFIG_X86" = "y" ]; then
3393+ bool 'Disable privileged I/O' CONFIG_GRKERNSEC_IO
3394+ if [ "$CONFIG_GRKERNSEC_IO" = "y" ]; then
3395+ define_bool CONFIG_RTC y
3396+ fi
3397+fi
3398+bool 'Hide kernel symbols' CONFIG_GRKERNSEC_HIDESYM
3399+endmenu
3400+mainmenu_option next_comment
3401+comment 'Role Based Access Control Options'
3402+bool 'Hide kernel processes' CONFIG_GRKERNSEC_ACL_HIDEKERN
3403+int 'Maximum tries before password lockout' CONFIG_GRKERNSEC_ACL_MAXTRIES 3
3404+int 'Time to wait after max password tries, in seconds' CONFIG_GRKERNSEC_ACL_TIMEOUT 30
3405+endmenu
3406+mainmenu_option next_comment
3407+comment 'Filesystem Protections'
3408+bool 'Proc restrictions' CONFIG_GRKERNSEC_PROC
3409+if [ "$CONFIG_GRKERNSEC_PROC" != "n" ]; then
3410+ bool ' Restrict to user only' CONFIG_GRKERNSEC_PROC_USER
3411+ if [ "$CONFIG_GRKERNSEC_PROC_USER" != "y" ]; then
3412+ bool ' Allow special group' CONFIG_GRKERNSEC_PROC_USERGROUP
3413+ if [ "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
3414+ int ' GID for special group' CONFIG_GRKERNSEC_PROC_GID 1001
3415+ fi
3416+ fi
3417+ if [ "$CONFIG_GRKERNSEC_PROC_USER" != "n" -o "$CONFIG_GRKERNSEC_PROC_USERGROUP" != "n" ]; then
3418+ bool ' Additional restrictions' CONFIG_GRKERNSEC_PROC_ADD
3419+ fi
3420+fi
3421+bool 'Linking restrictions' CONFIG_GRKERNSEC_LINK
3422+bool 'FIFO restrictions' CONFIG_GRKERNSEC_FIFO
3423+bool 'Chroot jail restrictions' CONFIG_GRKERNSEC_CHROOT
3424+if [ "$CONFIG_GRKERNSEC_CHROOT" != "n" ]; then
3425+bool ' Deny mounts' CONFIG_GRKERNSEC_CHROOT_MOUNT
3426+bool ' Deny double-chroots' CONFIG_GRKERNSEC_CHROOT_DOUBLE
3427+bool ' Deny pivot_root in chroot' CONFIG_GRKERNSEC_CHROOT_PIVOT
3428+bool ' Enforce chdir("/") on all chroots' CONFIG_GRKERNSEC_CHROOT_CHDIR
3429+bool ' Deny (f)chmod +s' CONFIG_GRKERNSEC_CHROOT_CHMOD
3430+bool ' Deny fchdir out of chroot' CONFIG_GRKERNSEC_CHROOT_FCHDIR
3431+bool ' Deny mknod' CONFIG_GRKERNSEC_CHROOT_MKNOD
3432+bool ' Deny shmat() out of chroot' CONFIG_GRKERNSEC_CHROOT_SHMAT
3433+bool ' Deny access to abstract AF_UNIX sockets out of chroot' CONFIG_GRKERNSEC_CHROOT_UNIX
3434+bool ' Protect outside processes' CONFIG_GRKERNSEC_CHROOT_FINDTASK
3435+bool ' Restrict priority changes' CONFIG_GRKERNSEC_CHROOT_NICE
3436+bool ' Deny sysctl writes in chroot' CONFIG_GRKERNSEC_CHROOT_SYSCTL
3437+bool ' Capability restrictions within chroot' CONFIG_GRKERNSEC_CHROOT_CAPS
3438+fi
3439+endmenu
3440+mainmenu_option next_comment
3441+comment 'Kernel Auditing'
3442+bool 'Single group for auditing' CONFIG_GRKERNSEC_AUDIT_GROUP
3443+if [ "$CONFIG_GRKERNSEC_AUDIT_GROUP" != "n" ]; then
3444+int ' GID for auditing' CONFIG_GRKERNSEC_AUDIT_GID 1007
3445+fi
3446+bool 'Exec logging' CONFIG_GRKERNSEC_EXECLOG
3447+bool 'Resource logging' CONFIG_GRKERNSEC_RESLOG
3448+bool 'Log execs within chroot' CONFIG_GRKERNSEC_CHROOT_EXECLOG
3449+bool 'Chdir logging' CONFIG_GRKERNSEC_AUDIT_CHDIR
3450+bool '(Un)Mount logging' CONFIG_GRKERNSEC_AUDIT_MOUNT
3451+bool 'IPC logging' CONFIG_GRKERNSEC_AUDIT_IPC
3452+bool 'Signal logging' CONFIG_GRKERNSEC_SIGNAL
3453+bool 'Fork failure logging' CONFIG_GRKERNSEC_FORKFAIL
3454+bool 'Time change logging' CONFIG_GRKERNSEC_TIME
3455+bool '/proc/<pid>/ipaddr support' CONFIG_GRKERNSEC_PROC_IPADDR
3456+endmenu
3457+mainmenu_option next_comment
3458+comment 'Executable Protections'
3459+bool 'Enforce RLIMIT_NPROC on execs' CONFIG_GRKERNSEC_EXECVE
3460+bool 'Dmesg(8) restriction' CONFIG_GRKERNSEC_DMESG
3461+bool 'Randomized PIDs' CONFIG_GRKERNSEC_RANDPID
3462+bool 'Trusted path execution' CONFIG_GRKERNSEC_TPE
3463+if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; then
3464+bool ' Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL
3465+int ' GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005
3466+fi
3467+endmenu
3468+mainmenu_option next_comment
3469+comment 'Network Protections'
3470+bool 'Larger entropy pools' CONFIG_GRKERNSEC_RANDNET
3471+bool 'Truly random TCP ISN selection' CONFIG_GRKERNSEC_RANDISN
3472+bool 'Randomized IP IDs' CONFIG_GRKERNSEC_RANDID
3473+bool 'Randomized TCP source ports' CONFIG_GRKERNSEC_RANDSRC
3474+bool 'Randomized RPC XIDs' CONFIG_GRKERNSEC_RANDRPC
3475+bool 'Socket restrictions' CONFIG_GRKERNSEC_SOCKET
3476+if [ "$CONFIG_GRKERNSEC_SOCKET" != "n" ]; then
3477+bool ' Deny any sockets to group' CONFIG_GRKERNSEC_SOCKET_ALL
3478+if [ "$CONFIG_GRKERNSEC_SOCKET_ALL" != "n" ]; then
3479+int ' GID to deny all sockets for:' CONFIG_GRKERNSEC_SOCKET_ALL_GID 1004
3480+fi
3481+bool ' Deny client sockets to group' CONFIG_GRKERNSEC_SOCKET_CLIENT
3482+if [ "$CONFIG_GRKERNSEC_SOCKET_CLIENT" != "n" ]; then
3483+int ' GID to deny client sockets for:' CONFIG_GRKERNSEC_SOCKET_CLIENT_GID 1003
3484+fi
3485+bool ' Deny server sockets to group' CONFIG_GRKERNSEC_SOCKET_SERVER
3486+if [ "$CONFIG_GRKERNSEC_SOCKET_SERVER" != "n" ]; then
3487+int ' GID to deny server sockets for:' CONFIG_GRKERNSEC_SOCKET_SERVER_GID 1002
3488+fi
3489+fi
3490+endmenu
3491+if [ "$CONFIG_SYSCTL" != "n" ]; then
3492+mainmenu_option next_comment
3493+comment 'Sysctl support'
3494+bool 'Sysctl support' CONFIG_GRKERNSEC_SYSCTL
3495+endmenu
3496+fi
3497+mainmenu_option next_comment
3498+comment 'Logging options'
3499+int 'Seconds in between log messages (minimum)' CONFIG_GRKERNSEC_FLOODTIME 10
3500+int 'Number of messages in a burst (maximum)' CONFIG_GRKERNSEC_FLOODBURST 4
3501+endmenu
3502+fi
3503diff -urN linux-2.4.22/grsecurity/Makefile linux-2.4.22/grsecurity/Makefile
3504--- linux-2.4.22/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
3505+++ linux-2.4.22/grsecurity/Makefile 2003-09-02 19:29:42.000000000 -0400
3506@@ -0,0 +1,24 @@
3507+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
3508+# during 2001, 2002, and 2003 it has been completely redesigned by
3509+# Brad Spengler
3510+#
3511+# All code in this directory and various hooks inserted throughout the kernel
3512+# are copyright Brad Spengler, and released under the GPL, unless otherwise
3513+# noted (as in obsd_rand.c)
3514+
3515+O_TARGET := grsec.o
3516+
3517+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
3518+ grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
3519+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o
3520+
3521+ifeq ($(CONFIG_GRKERNSEC),y)
3522+obj-y += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o obsd_rand.o \
3523+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
3524+ gracl_learn.o
3525+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
3526+else
3527+obj-y += grsec_disabled.o
3528+endif
3529+
3530+include $(TOPDIR)/Rules.make
3531diff -urN linux-2.4.22/grsecurity/gracl.c linux-2.4.22/grsecurity/gracl.c
3532--- linux-2.4.22/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
3533+++ linux-2.4.22/grsecurity/gracl.c 2003-09-02 19:50:30.000000000 -0400
3534@@ -0,0 +1,2740 @@
3535+/*
3536+ * grsecurity/gracl.c
3537+ * Copyright Brad Spengler 2001, 2002, 2003
3538+ *
3539+ */
3540+
3541+#include <linux/kernel.h>
3542+#include <linux/sched.h>
3543+#include <linux/mm.h>
3544+#include <linux/file.h>
3545+#include <linux/fs.h>
3546+#include <linux/proc_fs.h>
3547+#include <linux/smp_lock.h>
3548+#include <linux/slab.h>
3549+#include <linux/vmalloc.h>
3550+#include <linux/types.h>
3551+#include <linux/capability.h>
3552+#include <linux/sysctl.h>
3553+#include <linux/gracl.h>
3554+#include <linux/gralloc.h>
3555+#include <linux/grsecurity.h>
3556+#include <linux/grinternal.h>
3557+
3558+#include <asm/uaccess.h>
3559+#include <asm/errno.h>
3560+#include <asm/mman.h>
3561+
3562+static struct acl_role_db acl_role_set;
3563+static struct acl_role_label *role_list_head;
3564+static struct name_db name_set;
3565+static struct name_db inodev_set;
3566+
3567+static struct acl_role_label *default_role;
3568+
3569+static u16 acl_sp_role_value;
3570+
3571+static DECLARE_MUTEX(gr_dev_sem);
3572+rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
3573+
3574+extern char *gr_shared_page[4][NR_CPUS];
3575+struct gr_arg *gr_usermode;
3576+
3577+static unsigned long gr_status = GR_STATUS_INIT;
3578+
3579+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
3580+extern void gr_clear_learn_entries(void);
3581+
3582+#ifdef CONFIG_GRKERNSEC_RESLOG
3583+extern __inline__ void gr_log_resource(const struct task_struct *task,
3584+ const int res,
3585+ const unsigned long wanted);
3586+#endif
3587+
3588+unsigned char *gr_system_salt;
3589+unsigned char *gr_system_sum;
3590+
3591+static struct sprole_pw **acl_special_roles = NULL;
3592+static __u16 num_sprole_pws = 0;
3593+
3594+static struct acl_role_label *kernel_role = NULL;
3595+
3596+/* The following are used to keep a place held in the hash table when we move
3597+ entries around. They can be replaced during insert. */
3598+
3599+static struct acl_subject_label *deleted_subject;
3600+static struct acl_object_label *deleted_object;
3601+static struct name_entry *deleted_inodev;
3602+
3603+/* for keeping track of the last and final allocated subjects, since
3604+ nested subject parsing is tricky
3605+*/
3606+static struct acl_subject_label *s_last = NULL;
3607+static struct acl_subject_label *s_final = NULL;
3608+
3609+static unsigned int gr_auth_attempts = 0;
3610+static unsigned long gr_auth_expires = 0UL;
3611+
3612+extern int gr_init_uidset(void);
3613+extern void gr_free_uidset(void);
3614+extern void gr_remove_uid(uid_t uid);
3615+extern int gr_find_uid(uid_t uid);
3616+
3617+__inline__ int
3618+gr_acl_is_enabled(void)
3619+{
3620+ return (gr_status & GR_READY);
3621+}
3622+
3623+__inline__ int
3624+gr_acl_tpe_check(void)
3625+{
3626+ if (unlikely(!(gr_status & GR_READY)))
3627+ return 0;
3628+ if (current->role->roletype & GR_ROLE_TPE)
3629+ return 1;
3630+ else
3631+ return 0;
3632+}
3633+
3634+int
3635+gr_handle_rawio(const struct inode *inode)
3636+{
3637+ if (inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO) &&
3638+ ((gr_status & GR_READY)
3639+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
3640+ || (grsec_enable_chroot_caps && proc_is_chrooted(current))
3641+#endif
3642+ ))
3643+ return 1;
3644+ return 0;
3645+}
3646+
3647+
3648+static __inline__ int
3649+gr_streq(const char *a, const char *b, const __u16 lena, const __u16 lenb)
3650+{
3651+ int i;
3652+ unsigned long *l1;
3653+ unsigned long *l2;
3654+ unsigned char *c1;
3655+ unsigned char *c2;
3656+ int num_longs;
3657+
3658+ if (likely(lena != lenb))
3659+ return 0;
3660+
3661+ l1 = (unsigned long *)a;
3662+ l2 = (unsigned long *)b;
3663+
3664+ num_longs = lena / sizeof(unsigned long);
3665+
3666+ for (i = num_longs; i--; l1++, l2++) {
3667+ if (unlikely(*l1 != *l2))
3668+ return 0;
3669+ }
3670+
3671+ c1 = (unsigned char *) l1;
3672+ c2 = (unsigned char *) l2;
3673+
3674+ i = lena - (num_longs * sizeof(unsigned long));
3675+
3676+ for (; i--; c1++, c2++) {
3677+ if (unlikely(*c1 != *c2))
3678+ return 0;
3679+ }
3680+
3681+ return 1;
3682+}
3683+
3684+static __inline__ char *
3685+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
3686+ char *buf, int buflen)
3687+{
3688+ char *res;
3689+ struct dentry *our_dentry;
3690+ struct vfsmount *our_mount;
3691+ struct vfsmount *rootmnt;
3692+ struct dentry *root;
3693+
3694+ our_dentry = (struct dentry *) dentry;
3695+ our_mount = (struct vfsmount *) vfsmnt;
3696+
3697+ read_lock(&child_reaper->fs->lock);
3698+ rootmnt = mntget(child_reaper->fs->rootmnt);
3699+ root = dget(child_reaper->fs->root);
3700+ read_unlock(&child_reaper->fs->lock);
3701+
3702+ spin_lock(&dcache_lock);
3703+ res = __d_path(our_dentry, our_mount, root, rootmnt, buf, buflen);
3704+ spin_unlock(&dcache_lock);
3705+ dput(root);
3706+ mntput(rootmnt);
3707+ return res;
3708+}
3709+
3710+char *
3711+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
3712+{
3713+ return d_real_path(dentry, mnt, gr_shared_page[0][smp_processor_id()],
3714+ PAGE_SIZE);
3715+}
3716+
3717+char *
3718+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
3719+{
3720+ return d_real_path(dentry, mnt, gr_shared_page[1][smp_processor_id()],
3721+ PAGE_SIZE);
3722+}
3723+
3724+char *
3725+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
3726+{
3727+ return d_real_path(dentry, mnt, gr_shared_page[2][smp_processor_id()],
3728+ PAGE_SIZE);
3729+}
3730+
3731+char *
3732+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
3733+{
3734+ return d_real_path(dentry, mnt, gr_shared_page[3][smp_processor_id()],
3735+ PAGE_SIZE);
3736+}
3737+
3738+__inline__ __u32
3739+to_gr_audit(const __u32 reqmode)
3740+{
3741+ __u32 retmode = 0;
3742+
3743+ retmode |= (reqmode & GR_READ) ? GR_AUDIT_READ : 0;
3744+ retmode |= (reqmode & GR_WRITE) ? GR_AUDIT_WRITE | GR_AUDIT_APPEND : 0;
3745+ retmode |= (reqmode & GR_APPEND) ? GR_AUDIT_APPEND : 0;
3746+ retmode |= (reqmode & GR_EXEC) ? GR_AUDIT_EXEC : 0;
3747+ retmode |= (reqmode & GR_INHERIT) ? GR_AUDIT_INHERIT : 0;
3748+ retmode |= (reqmode & GR_FIND) ? GR_AUDIT_FIND : 0;
3749+ retmode |= (reqmode & GR_SETID) ? GR_AUDIT_SETID : 0;
3750+ retmode |= (reqmode & GR_CREATE) ? GR_AUDIT_CREATE : 0;
3751+ retmode |= (reqmode & GR_DELETE) ? GR_AUDIT_DELETE : 0;
3752+
3753+ return retmode;
3754+}
3755+
3756+__inline__ struct acl_role_label *
3757+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
3758+ const gid_t gid)
3759+{
3760+ unsigned long index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
3761+ struct acl_role_label *match;
3762+ struct role_allowed_ip *ipp;
3763+ __u8 i = 0;
3764+
3765+ match = acl_role_set.r_hash[index];
3766+
3767+ while (match
3768+ && (match->uidgid != uid || !(match->roletype & GR_ROLE_USER))) {
3769+ index = (index + (1 << i)) % acl_role_set.r_size;
3770+ match = acl_role_set.r_hash[index];
3771+ i = (i + 1) % 32;
3772+ }
3773+
3774+ if (!match || match->uidgid != uid || !(match->roletype & GR_ROLE_USER)) {
3775+ try_group:
3776+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
3777+ match = acl_role_set.r_hash[index];
3778+ i = 0;
3779+
3780+ while (match
3781+ && (match->uidgid != gid
3782+ || !(match->roletype & GR_ROLE_GROUP))) {
3783+ index = (index + (1 << i)) % acl_role_set.r_size;
3784+ match = acl_role_set.r_hash[index];
3785+ i = (i + 1) % 32;
3786+ }
3787+
3788+ if (!match || match->uidgid != gid
3789+ || !(match->roletype & GR_ROLE_GROUP))
3790+ match = default_role;
3791+ else if (likely(!match->allowed_ips)) {
3792+ return match;
3793+ } else {
3794+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
3795+ if (likely
3796+ ((task->curr_ip & ipp->netmask) ==
3797+ (ipp->addr & ipp->netmask)))
3798+ return match;
3799+ }
3800+ match = default_role;
3801+ }
3802+ } else if (likely(!match->allowed_ips)) {
3803+ return match;
3804+ } else {
3805+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
3806+ if (likely
3807+ ((task->curr_ip & ipp->netmask) ==
3808+ (ipp->addr & ipp->netmask)))
3809+ return match;
3810+ }
3811+ goto try_group;
3812+ }
3813+
3814+ return match;
3815+}
3816+
3817+__inline__ struct acl_subject_label *
3818+lookup_acl_subj_label(const ino_t ino, const kdev_t dev,
3819+ const struct acl_role_label *role)
3820+{
3821+ unsigned long subj_size = role->subj_hash_size;
3822+ struct acl_subject_label **s_hash = role->subj_hash;
3823+ unsigned long index = fhash(ino, dev, subj_size);
3824+ struct acl_subject_label *match;
3825+ __u8 i = 0;
3826+
3827+ match = s_hash[index];
3828+
3829+ while (match && (match->inode != ino || match->device != dev ||
3830+ (match->mode & GR_DELETED))) {
3831+ index = (index + (1 << i)) % subj_size;
3832+ match = s_hash[index];
3833+ i = (i + 1) % 32;
3834+ }
3835+
3836+ if (unlikely(match && (match != deleted_subject) &&
3837+ (match->inode == ino) && (match->device == dev) &&
3838+ !(match->mode & GR_DELETED)))
3839+ return match;
3840+ else
3841+ return NULL;
3842+}
3843+
3844+static __inline__ struct acl_object_label *
3845+lookup_acl_obj_label(const ino_t ino, const kdev_t dev,
3846+ const struct acl_subject_label *subj)
3847+{
3848+ unsigned long obj_size = subj->obj_hash_size;
3849+ struct acl_object_label **o_hash = subj->obj_hash;
3850+ unsigned long index = fhash(ino, dev, obj_size);
3851+ struct acl_object_label *match;
3852+ __u8 i = 0;
3853+
3854+ match = o_hash[index];
3855+
3856+ while (match && (match->inode != ino || match->device != dev ||
3857+ (match->mode & GR_DELETED))) {
3858+ index = (index + (1 << i)) % obj_size;
3859+ match = o_hash[index];
3860+ i = (i + 1) % 32;
3861+ }
3862+
3863+ if (unlikely(match && (match != deleted_object) &&
3864+ (match->inode == ino) && (match->device == dev) &&
3865+ !(match->mode & GR_DELETED)))
3866+ return match;
3867+ else
3868+ return NULL;
3869+}
3870+
3871+static __inline__ struct acl_object_label *
3872+lookup_acl_obj_label_create(const ino_t ino, const kdev_t dev,
3873+ const struct acl_subject_label *subj)
3874+{
3875+ unsigned long obj_size = subj->obj_hash_size;
3876+ struct acl_object_label **o_hash = subj->obj_hash;
3877+ unsigned long index = fhash(ino, dev, obj_size);
3878+ struct acl_object_label *match;
3879+ __u8 i = 0;
3880+
3881+ match = o_hash[index];
3882+
3883+ while (match && (match->inode != ino || match->device != dev ||
3884+ !(match->mode & GR_DELETED))) {
3885+ index = (index + (1 << i)) % obj_size;
3886+ match = o_hash[index];
3887+ i = (i + 1) % 32;
3888+ }
3889+
3890+ if (unlikely(match && (match != deleted_object) &&
3891+ (match->inode == ino) && (match->device == dev) &&
3892+ (match->mode & GR_DELETED)))
3893+ return match;
3894+
3895+ i = 0;
3896+ index = fhash(ino, dev, obj_size);
3897+ match = o_hash[index];
3898+
3899+ while (match && (match->inode != ino || match->device != dev ||
3900+ (match->mode & GR_DELETED))) {
3901+ index = (index + (1 << i)) % obj_size;
3902+ match = o_hash[index];
3903+ i = (i + 1) % 32;
3904+ }
3905+
3906+ if (unlikely(match && (match != deleted_object) &&
3907+ (match->inode == ino) && (match->device == dev) &&
3908+ !(match->mode & GR_DELETED)))
3909+ return match;
3910+ else
3911+ return NULL;
3912+}
3913+
3914+static __inline__ struct name_entry *
3915+lookup_name_entry(const char *name)
3916+{
3917+ __u16 len = strlen(name);
3918+ unsigned long index = nhash(name, len, name_set.n_size);
3919+ struct name_entry *match;
3920+ __u8 i = 0;
3921+
3922+ match = name_set.n_hash[index];
3923+
3924+ while (match && !gr_streq(match->name, name, match->len, len)) {
3925+ index = (index + (1 << i)) % name_set.n_size;
3926+ match = name_set.n_hash[index];
3927+ i = (i + 1) % 32;
3928+ }
3929+
3930+ if (unlikely(!match || !gr_streq(match->name, name, match->len, len)))
3931+ return NULL;
3932+ else
3933+ return match;
3934+}
3935+
3936+static __inline__ struct name_entry *
3937+lookup_inodev_entry(const ino_t ino, const kdev_t dev)
3938+{
3939+ unsigned long index = fhash(ino, dev, inodev_set.n_size);
3940+ struct name_entry *match;
3941+ __u8 i = 0;
3942+
3943+ match = inodev_set.n_hash[index];
3944+
3945+ while (match && (match->inode != ino || match->device != dev)) {
3946+ index = (index + (1 << i)) % inodev_set.n_size;
3947+ match = inodev_set.n_hash[index];
3948+ i = (i + 1) % 32;
3949+ }
3950+
3951+ if (unlikely(match && (match != deleted_inodev) &&
3952+ (match->inode == ino) && (match->device == dev)))
3953+ return match;
3954+ else
3955+ return NULL;
3956+}
3957+
3958+static void
3959+insert_inodev_entry(struct name_entry *nentry)
3960+{
3961+ unsigned long index = fhash(nentry->inode, nentry->device,
3962+ inodev_set.n_size);
3963+ struct name_entry **curr;
3964+ __u8 i = 0;
3965+
3966+ curr = &inodev_set.n_hash[index];
3967+
3968+ while (*curr && *curr != deleted_inodev) {
3969+ index = (index + (1 << i)) % inodev_set.n_size;
3970+ curr = &inodev_set.n_hash[index];
3971+ i = (i + 1) % 32;
3972+ }
3973+
3974+ *curr = nentry;
3975+
3976+ return;
3977+}
3978+
3979+static void
3980+insert_acl_role_label(struct acl_role_label *role)
3981+{
3982+ unsigned long index =
3983+ rhash(role->uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
3984+ struct acl_role_label **curr;
3985+ __u8 i = 0;
3986+
3987+ curr = &acl_role_set.r_hash[index];
3988+
3989+ while (*curr) {
3990+ index = (index + (1 << i)) % acl_role_set.r_size;
3991+ curr = &acl_role_set.r_hash[index];
3992+ i = (i + 1) % 32;
3993+ }
3994+
3995+ *curr = role;
3996+
3997+ return;
3998+}
3999+
4000+static int
4001+insert_name_entry(char *name, const ino_t inode, const kdev_t device)
4002+{
4003+ struct name_entry **curr;
4004+ __u8 i = 0;
4005+ __u16 len = strlen(name);
4006+ unsigned long index = nhash(name, len, name_set.n_size);
4007+
4008+ curr = &name_set.n_hash[index];
4009+
4010+ while (*curr && !gr_streq((*curr)->name, name, (*curr)->len, len)) {
4011+ index = (index + (1 << i)) % name_set.n_size;
4012+ curr = &name_set.n_hash[index];
4013+ i = (i + 1) % 32;
4014+ }
4015+
4016+ if (!(*curr)) {
4017+ struct name_entry *nentry =
4018+ acl_alloc(sizeof (struct name_entry));
4019+ if (!nentry)
4020+ return 0;
4021+ nentry->name = name;
4022+ nentry->inode = inode;
4023+ nentry->device = device;
4024+ nentry->len = len;
4025+ *curr = nentry;
4026+ /* insert us into the table searchable by inode/dev */
4027+ insert_inodev_entry(nentry);
4028+ }
4029+
4030+ return 1;
4031+}
4032+
4033+static void
4034+insert_acl_obj_label(struct acl_object_label *obj,
4035+ struct acl_subject_label *subj)
4036+{
4037+ unsigned long index =
4038+ fhash(obj->inode, obj->device, subj->obj_hash_size);
4039+ struct acl_object_label **curr;
4040+ __u8 i = 0;
4041+
4042+ curr = &subj->obj_hash[index];
4043+
4044+ while (*curr && *curr != deleted_object) {
4045+ index = (index + (1 << i)) % subj->obj_hash_size;
4046+ curr = &subj->obj_hash[index];
4047+ i = (i + 1) % 32;
4048+ }
4049+
4050+ *curr = obj;
4051+
4052+ return;
4053+}
4054+
4055+static void
4056+insert_acl_subj_label(struct acl_subject_label *obj,
4057+ struct acl_role_label *role)
4058+{
4059+ unsigned long subj_size = role->subj_hash_size;
4060+ struct acl_subject_label **s_hash = role->subj_hash;
4061+ unsigned long index = fhash(obj->inode, obj->device, subj_size);
4062+ struct acl_subject_label **curr;
4063+ __u8 i = 0;
4064+
4065+ curr = &s_hash[index];
4066+
4067+ while (*curr && *curr != deleted_subject) {
4068+ index = (index + (1 << i)) % subj_size;
4069+ curr = &s_hash[index];
4070+ i = (i + 1) % 32;
4071+ }
4072+
4073+ *curr = obj;
4074+
4075+ return;
4076+}
4077+
4078+static void **
4079+create_table(__u32 * len)
4080+{
4081+ unsigned long table_sizes[] = {
4082+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
4083+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
4084+ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
4085+ 268435399, 536870909, 1073741789, 2147483647
4086+ };
4087+ void *newtable = NULL;
4088+ unsigned int pwr = 0;
4089+
4090+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
4091+ table_sizes[pwr] <= (2 * (*len)))
4092+ pwr++;
4093+
4094+ if (table_sizes[pwr] <= (2 * (*len)))
4095+ return newtable;
4096+
4097+ if ((table_sizes[pwr] * sizeof (void *)) <= PAGE_SIZE)
4098+ newtable =
4099+ kmalloc(table_sizes[pwr] * sizeof (void *), GFP_KERNEL);
4100+ else
4101+ newtable = vmalloc(table_sizes[pwr] * sizeof (void *));
4102+
4103+ *len = table_sizes[pwr];
4104+
4105+ return newtable;
4106+}
4107+
4108+static int
4109+init_variables(const unsigned long acl_obj_size,
4110+ const unsigned long acl_subj_size,
4111+ const unsigned long acl_ip_size,
4112+ const unsigned long acl_role_size,
4113+ const unsigned long allowed_ip_size,
4114+ const unsigned long acl_trans_size,
4115+ const __u16 num_sprole_pws)
4116+{
4117+ unsigned long stacksize;
4118+
4119+ acl_role_set.r_size = acl_role_size;
4120+ name_set.n_size = (acl_obj_size + acl_subj_size);
4121+ inodev_set.n_size = (acl_obj_size + acl_subj_size);
4122+
4123+ if (!gr_init_uidset())
4124+ return 1;
4125+
4126+ /* set up the stack that holds allocation info */
4127+
4128+ stacksize = (3 * acl_obj_size) + (2 * acl_role_size) +
4129+ (4 * acl_subj_size) + acl_ip_size + (2 * acl_trans_size) +
4130+ allowed_ip_size + (2 * num_sprole_pws) + 5;
4131+
4132+ if (!acl_alloc_stack_init(stacksize))
4133+ return 1;
4134+
4135+ /* create our empty, fake deleted acls */
4136+ deleted_subject =
4137+ (struct acl_subject_label *)
4138+ acl_alloc(sizeof (struct acl_subject_label));
4139+ deleted_object =
4140+ (struct acl_object_label *)
4141+ acl_alloc(sizeof (struct acl_object_label));
4142+ deleted_inodev =
4143+ (struct name_entry *) acl_alloc(sizeof (struct name_entry));
4144+
4145+ if (!deleted_subject || !deleted_object || !deleted_inodev)
4146+ return 1;
4147+
4148+ memset(deleted_subject, 0, sizeof (struct acl_subject_label));
4149+ memset(deleted_object, 0, sizeof (struct acl_object_label));
4150+ memset(deleted_inodev, 0, sizeof (struct name_entry));
4151+
4152+ /* We only want 50% full tables for now */
4153+
4154+ acl_role_set.r_hash =
4155+ (struct acl_role_label **) create_table(&acl_role_set.r_size);
4156+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size);
4157+ inodev_set.n_hash =
4158+ (struct name_entry **) create_table(&inodev_set.n_size);
4159+
4160+ if (!acl_role_set.r_hash || !name_set.n_hash || !inodev_set.n_hash)
4161+ return 1;
4162+ memset(acl_role_set.r_hash, 0,
4163+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
4164+ memset(name_set.n_hash, 0,
4165+ sizeof (struct name_entry *) * name_set.n_size);
4166+ memset(inodev_set.n_hash, 0,
4167+ sizeof (struct name_entry *) * inodev_set.n_size);
4168+
4169+ return 0;
4170+}
4171+
4172+static void
4173+free_variables(void)
4174+{
4175+ struct acl_subject_label *s;
4176+ struct acl_role_label *r;
4177+ struct task_struct *task;
4178+
4179+ gr_clear_learn_entries();
4180+
4181+ read_lock(&tasklist_lock);
4182+ for_each_task(task) {
4183+ task->acl_sp_role = 0;
4184+ task->acl_role_id = 0;
4185+ task->acl = NULL;
4186+ task->role = NULL;
4187+ }
4188+ read_unlock(&tasklist_lock);
4189+
4190+ /* free all object hash tables */
4191+
4192+ if (role_list_head) {
4193+ for (r = role_list_head; r; r = r->next) {
4194+ if (!r->subj_hash)
4195+ break;
4196+ for (s = r->proc_subject; s; s = s->next) {
4197+ if (!s->obj_hash)
4198+ break;
4199+ if ((s->obj_hash_size *
4200+ sizeof (struct acl_object_label *)) <=
4201+ PAGE_SIZE)
4202+ kfree(s->obj_hash);
4203+ else
4204+ vfree(s->obj_hash);
4205+ }
4206+ if ((r->subj_hash_size *
4207+ sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
4208+ kfree(r->subj_hash);
4209+ else
4210+ vfree(r->subj_hash);
4211+ }
4212+ }
4213+
4214+ acl_free_all();
4215+
4216+ if (acl_role_set.r_hash) {
4217+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
4218+ PAGE_SIZE)
4219+ kfree(acl_role_set.r_hash);
4220+ else
4221+ vfree(acl_role_set.r_hash);
4222+ }
4223+ if (name_set.n_hash) {
4224+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
4225+ PAGE_SIZE)
4226+ kfree(name_set.n_hash);
4227+ else
4228+ vfree(name_set.n_hash);
4229+ }
4230+
4231+ if (inodev_set.n_hash) {
4232+ if ((inodev_set.n_size * sizeof (struct name_entry *)) <=
4233+ PAGE_SIZE)
4234+ kfree(inodev_set.n_hash);
4235+ else
4236+ vfree(inodev_set.n_hash);
4237+ }
4238+
4239+ gr_free_uidset();
4240+
4241+ memset(&name_set, 0, sizeof (struct name_db));
4242+ memset(&inodev_set, 0, sizeof (struct name_db));
4243+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
4244+
4245+ role_list_head = NULL;
4246+ default_role = NULL;
4247+
4248+ return;
4249+}
4250+
4251+static __u32
4252+count_user_objs(struct acl_object_label *userp)
4253+{
4254+ struct acl_object_label o_tmp;
4255+ __u32 num = 0;
4256+
4257+ while (userp) {
4258+ if (copy_from_user(&o_tmp, userp,
4259+ sizeof (struct acl_object_label)))
4260+ break;
4261+
4262+ userp = o_tmp.prev;
4263+ num++;
4264+ }
4265+
4266+ return num;
4267+}
4268+
4269+static struct acl_subject_label *
4270+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
4271+
4272+static int
4273+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
4274+ struct acl_role_label *role)
4275+{
4276+ struct acl_object_label *o_tmp;
4277+ unsigned int len;
4278+ char *tmp;
4279+
4280+ while (userp) {
4281+ if ((o_tmp = (struct acl_object_label *)
4282+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
4283+ return -ENOMEM;
4284+
4285+ if (copy_from_user(o_tmp, userp,
4286+ sizeof (struct acl_object_label)))
4287+ return -EFAULT;
4288+
4289+ userp = o_tmp->prev;
4290+
4291+ len = strnlen_user(o_tmp->filename, PATH_MAX);
4292+
4293+ if (!len || len >= PATH_MAX)
4294+ return -EINVAL;
4295+
4296+ if ((tmp = (char *) acl_alloc(len)) == NULL)
4297+ return -ENOMEM;
4298+
4299+ if (copy_from_user(tmp, o_tmp->filename, len))
4300+ return -EFAULT;
4301+
4302+ o_tmp->filename = tmp;
4303+
4304+ insert_acl_obj_label(o_tmp, subj);
4305+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
4306+ o_tmp->device))
4307+ return -ENOMEM;
4308+
4309+ if (o_tmp->nested) {
4310+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
4311+ if (IS_ERR(o_tmp->nested))
4312+ return PTR_ERR(o_tmp->nested);
4313+
4314+ s_final = o_tmp->nested;
4315+ }
4316+ }
4317+
4318+ return 0;
4319+}
4320+
4321+static __u32
4322+count_user_subjs(struct acl_subject_label *userp)
4323+{
4324+ struct acl_subject_label s_tmp;
4325+ __u32 num = 0;
4326+
4327+ while (userp) {
4328+ if (copy_from_user(&s_tmp, userp,
4329+ sizeof (struct acl_subject_label)))
4330+ break;
4331+
4332+ userp = s_tmp.prev;
4333+ /* do not count nested subjects against this count, since
4334+ they are not included in the hash table, but are
4335+ attached to objects. We have already counted
4336+ the subjects in userspace for the allocation
4337+ stack
4338+ */
4339+ if (!s_tmp.parent_subject)
4340+ num++;
4341+ }
4342+
4343+ return num;
4344+}
4345+
4346+static int
4347+copy_user_allowedips(struct acl_role_label *rolep)
4348+{
4349+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
4350+
4351+ ruserip = rolep->allowed_ips;
4352+
4353+ while (ruserip) {
4354+ rlast = rtmp;
4355+
4356+ if ((rtmp = (struct role_allowed_ip *)
4357+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
4358+ return -ENOMEM;
4359+
4360+ if (copy_from_user(rtmp, ruserip,
4361+ sizeof (struct role_allowed_ip)))
4362+ return -EFAULT;
4363+
4364+ ruserip = rtmp->prev;
4365+
4366+ if (!rlast) {
4367+ rtmp->prev = NULL;
4368+ rolep->allowed_ips = rtmp;
4369+ } else {
4370+ rlast->next = rtmp;
4371+ rtmp->prev = rlast;
4372+ }
4373+
4374+ if (!ruserip)
4375+ rtmp->next = NULL;
4376+ }
4377+
4378+ return 0;
4379+}
4380+
4381+static int
4382+copy_user_transitions(struct acl_role_label *rolep)
4383+{
4384+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
4385+ unsigned int len;
4386+ char *tmp;
4387+
4388+ rusertp = rolep->transitions;
4389+
4390+ while (rusertp) {
4391+ rlast = rtmp;
4392+
4393+ if ((rtmp = (struct role_transition *)
4394+ acl_alloc(sizeof (struct role_transition))) == NULL)
4395+ return -ENOMEM;
4396+
4397+ if (copy_from_user(rtmp, rusertp,
4398+ sizeof (struct role_transition)))
4399+ return -EFAULT;
4400+
4401+ rusertp = rtmp->prev;
4402+
4403+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
4404+
4405+ if (!len || len >= GR_SPROLE_LEN)
4406+ return -EINVAL;
4407+
4408+ if ((tmp = (char *) acl_alloc(len)) == NULL)
4409+ return -ENOMEM;
4410+
4411+ if (copy_from_user(tmp, rtmp->rolename, len))
4412+ return -EFAULT;
4413+
4414+ rtmp->rolename = tmp;
4415+
4416+ if (!rlast) {
4417+ rtmp->prev = NULL;
4418+ rolep->transitions = rtmp;
4419+ } else {
4420+ rlast->next = rtmp;
4421+ rtmp->prev = rlast;
4422+ }
4423+
4424+ if (!rusertp)
4425+ rtmp->next = NULL;
4426+ }
4427+
4428+ return 0;
4429+}
4430+
4431+static struct acl_subject_label *
4432+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
4433+{
4434+ struct acl_subject_label *s_tmp = NULL;
4435+ unsigned int len;
4436+ char *tmp;
4437+ __u32 num_objs;
4438+ struct acl_ip_label **i_tmp, *i_utmp2;
4439+ unsigned long i_num;
4440+ int err;
4441+
4442+
4443+ if ((s_tmp = (struct acl_subject_label *)
4444+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
4445+ return ERR_PTR(-ENOMEM);
4446+
4447+ if (copy_from_user(s_tmp, userp,
4448+ sizeof (struct acl_subject_label)))
4449+ return ERR_PTR(-EFAULT);
4450+
4451+ if (!s_last) {
4452+ s_tmp->prev = NULL;
4453+ role->proc_subject = s_tmp;
4454+ } else {
4455+ s_last->next = s_tmp;
4456+ s_tmp->prev = s_last;
4457+ }
4458+
4459+ s_last = s_tmp;
4460+
4461+ len = strnlen_user(s_tmp->filename, PATH_MAX);
4462+
4463+ if (!len || len >= PATH_MAX)
4464+ return ERR_PTR(-EINVAL);
4465+
4466+ if ((tmp = (char *) acl_alloc(len)) == NULL)
4467+ return ERR_PTR(-ENOMEM);
4468+
4469+ if (copy_from_user(tmp, s_tmp->filename, len))
4470+ return ERR_PTR(-EFAULT);
4471+
4472+ s_tmp->filename = tmp;
4473+
4474+ if (!strcmp(s_tmp->filename, "/"))
4475+ role->root_label = s_tmp;
4476+
4477+ /* set up object hash table */
4478+ num_objs = count_user_objs(s_tmp->proc_object);
4479+
4480+ s_tmp->obj_hash_size = num_objs;
4481+ s_tmp->obj_hash =
4482+ (struct acl_object_label **)
4483+ create_table(&(s_tmp->obj_hash_size));
4484+
4485+ if (!s_tmp->obj_hash)
4486+ return ERR_PTR(-ENOMEM);
4487+
4488+ memset(s_tmp->obj_hash, 0,
4489+ s_tmp->obj_hash_size *
4490+ sizeof (struct acl_object_label *));
4491+
4492+ /* copy before adding in objects, since a nested
4493+ acl could be found and be the final subject
4494+ copied
4495+ */
4496+
4497+ s_final = s_tmp;
4498+
4499+ /* add in objects */
4500+ err = copy_user_objs(s_tmp->proc_object, s_tmp, role);
4501+
4502+ if (err)
4503+ return ERR_PTR(err);
4504+
4505+ /* add in ip acls */
4506+
4507+ if (!s_tmp->ip_num) {
4508+ s_tmp->ips = NULL;
4509+ goto insert;
4510+ }
4511+
4512+ i_tmp =
4513+ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
4514+ sizeof (struct
4515+ acl_ip_label *));
4516+
4517+ if (!i_tmp)
4518+ return ERR_PTR(-ENOMEM);
4519+
4520+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
4521+ *(i_tmp + i_num) =
4522+ (struct acl_ip_label *)
4523+ acl_alloc(sizeof (struct acl_ip_label));
4524+ if (!*(i_tmp + i_num))
4525+ return ERR_PTR(-ENOMEM);
4526+
4527+ if (copy_from_user
4528+ (&i_utmp2, s_tmp->ips + i_num,
4529+ sizeof (struct acl_ip_label *)))
4530+ return ERR_PTR(-EFAULT);
4531+
4532+ if (copy_from_user
4533+ (*(i_tmp + i_num), i_utmp2,
4534+ sizeof (struct acl_ip_label)))
4535+ return ERR_PTR(-EFAULT);
4536+ }
4537+
4538+ s_tmp->ips = i_tmp;
4539+
4540+insert:
4541+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
4542+ s_tmp->device))
4543+ return ERR_PTR(-ENOMEM);
4544+
4545+ return s_tmp;
4546+}
4547+
4548+static int
4549+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
4550+{
4551+ struct acl_subject_label s_pre;
4552+ struct acl_subject_label * ret;
4553+ int err;
4554+
4555+ while (userp) {
4556+ if (copy_from_user(&s_pre, userp,
4557+ sizeof (struct acl_subject_label)))
4558+ return -EFAULT;
4559+
4560+ /* do not add nested subjects here, add
4561+ while parsing objects
4562+ */
4563+
4564+ if (s_pre.parent_subject) {
4565+ userp = s_pre.prev;
4566+ continue;
4567+ }
4568+
4569+ ret = do_copy_user_subj(userp, role);
4570+
4571+ err = PTR_ERR(ret);
4572+ if (IS_ERR(ret))
4573+ return err;
4574+
4575+ insert_acl_subj_label(ret, role);
4576+
4577+ userp = s_pre.prev;
4578+ }
4579+
4580+ s_final->next = NULL;
4581+
4582+ return 0;
4583+}
4584+
4585+static int
4586+copy_user_acl(struct gr_arg *arg)
4587+{
4588+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2, *r_last;
4589+ struct sprole_pw *sptmp;
4590+ unsigned long r_num;
4591+ unsigned int len;
4592+ char *tmp;
4593+ int err = 0;
4594+ __u16 i;
4595+ __u32 num_subjs;
4596+
4597+ /* we need a default and kernel role */
4598+ if (arg->role_db.r_entries < 2)
4599+ return -EINVAL;
4600+
4601+ /* copy special role authentication info from userspace */
4602+
4603+ num_sprole_pws = arg->num_sprole_pws;
4604+ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
4605+
4606+ if (!acl_special_roles) {
4607+ err = -ENOMEM;
4608+ goto cleanup;
4609+ }
4610+
4611+ for (i = 0; i < num_sprole_pws; i++) {
4612+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
4613+ if (!sptmp) {
4614+ err = -ENOMEM;
4615+ goto cleanup;
4616+ }
4617+ if (copy_from_user(sptmp, arg->sprole_pws + i,
4618+ sizeof (struct sprole_pw))) {
4619+ err = -EFAULT;
4620+ goto cleanup;
4621+ }
4622+
4623+ len =
4624+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
4625+
4626+ if (!len || len >= GR_SPROLE_LEN) {
4627+ err = -EINVAL;
4628+ goto cleanup;
4629+ }
4630+
4631+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
4632+ err = -ENOMEM;
4633+ goto cleanup;
4634+ }
4635+
4636+ if (copy_from_user(tmp, sptmp->rolename, len)) {
4637+ err = -EFAULT;
4638+ goto cleanup;
4639+ }
4640+
4641+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
4642+ printk(KERN_ALERT "Copying special role %s\n", tmp);
4643+#endif
4644+ sptmp->rolename = tmp;
4645+ acl_special_roles[i] = sptmp;
4646+ }
4647+
4648+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
4649+
4650+ for (r_num = 0; r_num < arg->role_db.r_entries; r_num++) {
4651+ r_last = r_tmp;
4652+
4653+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
4654+
4655+ if (!r_tmp) {
4656+ err = -ENOMEM;
4657+ goto cleanup;
4658+ }
4659+
4660+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
4661+ sizeof (struct acl_role_label *))) {
4662+ err = -EFAULT;
4663+ goto cleanup;
4664+ }
4665+
4666+ if (copy_from_user(r_tmp, r_utmp2,
4667+ sizeof (struct acl_role_label))) {
4668+ err = -EFAULT;
4669+ goto cleanup;
4670+ }
4671+
4672+ if (!r_last) {
4673+ r_tmp->prev = NULL;
4674+ role_list_head = r_tmp;
4675+ } else {
4676+ r_last->next = r_tmp;
4677+ r_tmp->prev = r_last;
4678+ }
4679+
4680+ if (r_num == (arg->role_db.r_entries - 1))
4681+ r_tmp->next = NULL;
4682+
4683+ len = strnlen_user(r_tmp->rolename, PATH_MAX);
4684+
4685+ if (!len || len >= PATH_MAX) {
4686+ err = -EINVAL;
4687+ goto cleanup;
4688+ }
4689+
4690+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
4691+ err = -ENOMEM;
4692+ goto cleanup;
4693+ }
4694+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
4695+ err = -EFAULT;
4696+ goto cleanup;
4697+ }
4698+ r_tmp->rolename = tmp;
4699+
4700+ if (!strcmp(r_tmp->rolename, "default")
4701+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
4702+ default_role = r_tmp;
4703+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
4704+ kernel_role = r_tmp;
4705+ }
4706+
4707+ num_subjs = count_user_subjs(r_tmp->proc_subject);
4708+
4709+ r_tmp->subj_hash_size = num_subjs;
4710+ r_tmp->subj_hash =
4711+ (struct acl_subject_label **)
4712+ create_table(&(r_tmp->subj_hash_size));
4713+
4714+ if (!r_tmp->subj_hash) {
4715+ err = -ENOMEM;
4716+ goto cleanup;
4717+ }
4718+
4719+ err = copy_user_allowedips(r_tmp);
4720+ if (err)
4721+ goto cleanup;
4722+
4723+ err = copy_user_transitions(r_tmp);
4724+ if (err)
4725+ goto cleanup;
4726+
4727+ memset(r_tmp->subj_hash, 0,
4728+ r_tmp->subj_hash_size *
4729+ sizeof (struct acl_subject_label *));
4730+
4731+ s_last = NULL;
4732+
4733+ err = copy_user_subjs(r_tmp->proc_subject, r_tmp);
4734+
4735+ if (err)
4736+ goto cleanup;
4737+
4738+ insert_acl_role_label(r_tmp);
4739+ }
4740+
4741+ goto return_err;
4742+ cleanup:
4743+ free_variables();
4744+ return_err:
4745+ return err;
4746+
4747+}
4748+
4749+static int
4750+gracl_init(struct gr_arg *args)
4751+{
4752+ int error = 0;
4753+
4754+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
4755+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
4756+
4757+ if (init_variables(args->role_db.o_entries, args->role_db.s_entries,
4758+ args->role_db.i_entries, args->role_db.r_entries,
4759+ args->role_db.a_entries, args->role_db.t_entries,
4760+ args->num_sprole_pws)) {
4761+ security_alert_good(GR_INITF_ACL_MSG, GR_VERSION);
4762+ error = -ENOMEM;
4763+ free_variables();
4764+ goto out;
4765+ }
4766+
4767+ error = copy_user_acl(args);
4768+ if (error)
4769+ goto out;
4770+
4771+ if ((error = gr_set_acls(0))) {
4772+ free_variables();
4773+ goto out;
4774+ }
4775+
4776+ gr_status |= GR_READY;
4777+ out:
4778+ return error;
4779+}
4780+
4781+static struct acl_object_label *
4782+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
4783+ const struct acl_subject_label *subj)
4784+{
4785+ struct dentry *dentry = (struct dentry *) l_dentry;
4786+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
4787+ struct dentry *root;
4788+ struct vfsmount *rootmnt;
4789+ struct acl_object_label *retval;
4790+
4791+ read_lock(&child_reaper->fs->lock);
4792+ rootmnt = mntget(child_reaper->fs->rootmnt);
4793+ root = dget(child_reaper->fs->root);
4794+ read_unlock(&child_reaper->fs->lock);
4795+ spin_lock(&dcache_lock);
4796+
4797+ for (;;) {
4798+ if (unlikely(dentry == root && mnt == rootmnt))
4799+ break;
4800+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
4801+ if (mnt->mnt_parent == mnt)
4802+ break;
4803+
4804+ read_lock(&gr_inode_lock);
4805+ retval =
4806+ lookup_acl_obj_label(dentry->d_inode->i_ino,
4807+ dentry->d_inode->i_dev, subj);
4808+ read_unlock(&gr_inode_lock);
4809+ if (unlikely(retval != NULL))
4810+ goto out;
4811+
4812+ dentry = mnt->mnt_mountpoint;
4813+ mnt = mnt->mnt_parent;
4814+ continue;
4815+ }
4816+
4817+ read_lock(&gr_inode_lock);
4818+ retval =
4819+ lookup_acl_obj_label(dentry->d_inode->i_ino,
4820+ dentry->d_inode->i_dev, subj);
4821+ read_unlock(&gr_inode_lock);
4822+ if (unlikely(retval != NULL))
4823+ goto out;
4824+
4825+ dentry = dentry->d_parent;
4826+ }
4827+
4828+ read_lock(&gr_inode_lock);
4829+ retval =
4830+ lookup_acl_obj_label(dentry->d_inode->i_ino, dentry->d_inode->i_dev,
4831+ subj);
4832+ read_unlock(&gr_inode_lock);
4833+
4834+ if (unlikely(retval == NULL)) {
4835+ read_lock(&gr_inode_lock);
4836+ retval =
4837+ lookup_acl_obj_label(root->d_inode->i_ino,
4838+ root->d_inode->i_dev, subj);
4839+ read_unlock(&gr_inode_lock);
4840+ }
4841+ out:
4842+ spin_unlock(&dcache_lock);
4843+ dput(root);
4844+ mntput(rootmnt);
4845+
4846+ return retval;
4847+}
4848+
4849+static struct acl_subject_label *
4850+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
4851+ const struct acl_role_label *role)
4852+{
4853+ struct dentry *dentry = (struct dentry *) l_dentry;
4854+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
4855+ struct dentry *root;
4856+ struct vfsmount *rootmnt;
4857+ struct acl_subject_label *retval;
4858+
4859+ read_lock(&child_reaper->fs->lock);
4860+ rootmnt = mntget(child_reaper->fs->rootmnt);
4861+ root = dget(child_reaper->fs->root);
4862+ read_unlock(&child_reaper->fs->lock);
4863+ spin_lock(&dcache_lock);
4864+
4865+ for (;;) {
4866+ if (unlikely(dentry == root && mnt == rootmnt))
4867+ break;
4868+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
4869+ if (mnt->mnt_parent == mnt)
4870+ break;
4871+
4872+ read_lock(&gr_inode_lock);
4873+ retval =
4874+ lookup_acl_subj_label(dentry->d_inode->i_ino,
4875+ dentry->d_inode->i_dev, role);
4876+ read_unlock(&gr_inode_lock);
4877+ if (unlikely(retval != NULL))
4878+ goto out;
4879+
4880+ dentry = mnt->mnt_mountpoint;
4881+ mnt = mnt->mnt_parent;
4882+ continue;
4883+ }
4884+
4885+ read_lock(&gr_inode_lock);
4886+ retval =
4887+ lookup_acl_subj_label(dentry->d_inode->i_ino,
4888+ dentry->d_inode->i_dev, role);
4889+ read_unlock(&gr_inode_lock);
4890+ if (unlikely(retval != NULL))
4891+ goto out;
4892+
4893+ dentry = dentry->d_parent;
4894+ }
4895+
4896+ read_lock(&gr_inode_lock);
4897+ retval =
4898+ lookup_acl_subj_label(dentry->d_inode->i_ino,
4899+ dentry->d_inode->i_dev, role);
4900+ read_unlock(&gr_inode_lock);
4901+
4902+ if (unlikely(retval == NULL)) {
4903+ read_lock(&gr_inode_lock);
4904+ retval =
4905+ lookup_acl_subj_label(root->d_inode->i_ino,
4906+ root->d_inode->i_dev, role);
4907+ read_unlock(&gr_inode_lock);
4908+ }
4909+ out:
4910+ spin_unlock(&dcache_lock);
4911+ dput(root);
4912+ mntput(rootmnt);
4913+
4914+ return retval;
4915+}
4916+
4917+static __inline__ void
4918+gr_log_learn(const struct acl_role_label *role, const uid_t uid, const gid_t gid,
4919+ const struct task_struct *task, const char *pathname,
4920+ const __u32 mode)
4921+{
4922+ security_learn(GR_LEARN_AUDIT_MSG, role->rolename, role->roletype,
4923+ uid, gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
4924+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
4925+ 1, 1, pathname, (unsigned long) mode, NIPQUAD(task->curr_ip));
4926+
4927+ return;
4928+}
4929+
4930+__u32
4931+gr_check_link(const struct dentry * new_dentry,
4932+ const struct dentry * parent_dentry,
4933+ const struct vfsmount * parent_mnt,
4934+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
4935+{
4936+ struct acl_object_label *obj;
4937+ __u32 oldmode, newmode;
4938+
4939+ if (unlikely(!(gr_status & GR_READY)))
4940+ return (GR_WRITE | GR_CREATE);
4941+
4942+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
4943+ oldmode = obj->mode;
4944+
4945+ if (current->acl->mode & GR_LEARN)
4946+ oldmode |= (GR_WRITE | GR_CREATE);
4947+ newmode =
4948+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
4949+ oldmode | GR_CREATE | GR_AUDIT_CREATE |
4950+ GR_AUDIT_WRITE | GR_SUPPRESS);
4951+
4952+ if ((newmode & oldmode) == oldmode)
4953+ return newmode;
4954+ else if (current->acl->mode & GR_LEARN) {
4955+ gr_log_learn(current->role, current->uid, current->gid,
4956+ current, gr_to_filename(old_dentry, old_mnt), oldmode);
4957+ return (GR_WRITE | GR_CREATE);
4958+ } else if (newmode & GR_SUPPRESS)
4959+ return GR_SUPPRESS;
4960+ else
4961+ return 0;
4962+}
4963+
4964+__u32
4965+gr_search_file(const struct dentry * dentry, const __u32 mode,
4966+ const struct vfsmount * mnt)
4967+{
4968+ __u32 retval = mode;
4969+ struct acl_subject_label *curracl;
4970+ struct acl_object_label *currobj;
4971+
4972+ if (unlikely(!(gr_status & GR_READY)))
4973+ return (mode & ~GR_AUDITS);
4974+
4975+ curracl = current->acl;
4976+
4977+ currobj = chk_obj_label(dentry, mnt, curracl);
4978+ retval = currobj->mode & mode;
4979+
4980+ if (unlikely
4981+ ((curracl->mode & GR_LEARN) && (mode != GR_PTRACERD)
4982+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
4983+ __u32 new_mode = mode;
4984+
4985+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
4986+
4987+ retval = new_mode;
4988+
4989+ if (!(mode & GR_NOLEARN))
4990+ gr_log_learn(current->role, current->uid, current->gid,
4991+ current, gr_to_filename(dentry, mnt), new_mode);
4992+ }
4993+
4994+ return retval;
4995+}
4996+
4997+__u32
4998+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
4999+ const struct vfsmount * mnt, const __u32 mode)
5000+{
5001+ struct name_entry *match;
5002+ struct acl_object_label *matchpo;
5003+ struct acl_subject_label *curracl;
5004+ __u32 retval;
5005+
5006+ if (unlikely(!(gr_status & GR_READY)))
5007+ return (mode & ~GR_AUDITS);
5008+
5009+ match = lookup_name_entry(gr_to_filename(new_dentry, mnt));
5010+
5011+ if (!match)
5012+ goto check_parent;
5013+
5014+ curracl = current->acl;
5015+
5016+ read_lock(&gr_inode_lock);
5017+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
5018+ read_unlock(&gr_inode_lock);
5019+
5020+ if (matchpo) {
5021+ if ((matchpo->mode & mode) !=
5022+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
5023+ && curracl->mode & GR_LEARN) {
5024+ __u32 new_mode = mode;
5025+
5026+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
5027+
5028+ gr_log_learn(current->role, current->uid, current->gid,
5029+ current, gr_to_filename(new_dentry, mnt), new_mode);
5030+
5031+ return new_mode;
5032+ }
5033+ return (matchpo->mode & mode);
5034+ }
5035+
5036+ check_parent:
5037+ curracl = current->acl;
5038+
5039+ matchpo = chk_obj_label(parent, mnt, curracl);
5040+ retval = matchpo->mode & mode;
5041+
5042+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
5043+ && (curracl->mode & GR_LEARN)) {
5044+ __u32 new_mode = mode;
5045+
5046+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
5047+
5048+ gr_log_learn(current->role, current->uid, current->gid,
5049+ current, gr_to_filename(new_dentry, mnt), new_mode);
5050+ return new_mode;
5051+ }
5052+
5053+ return retval;
5054+}
5055+
5056+int
5057+gr_check_hidden_task(const struct task_struct *task)
5058+{
5059+ if (unlikely(!(gr_status & GR_READY)))
5060+ return 0;
5061+
5062+ if (!(task->acl->mode & GR_FIND) && !(current->acl->mode & GR_VIEW))
5063+ return 1;
5064+
5065+ return 0;
5066+}
5067+
5068+int
5069+gr_check_protected_task(const struct task_struct *task)
5070+{
5071+ if (unlikely(!(gr_status & GR_READY) || !task))
5072+ return 0;
5073+
5074+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL))
5075+ return 1;
5076+
5077+ return 0;
5078+}
5079+
5080+__inline__ void
5081+gr_copy_label(struct task_struct *tsk)
5082+{
5083+ tsk->used_accept = 0;
5084+ tsk->used_connect = 0;
5085+ tsk->acl_sp_role = 0;
5086+ tsk->acl_role_id = current->acl_role_id;
5087+ tsk->acl = current->acl;
5088+ tsk->role = current->role;
5089+ tsk->curr_ip = current->curr_ip;
5090+ if (current->exec_file)
5091+ get_file(current->exec_file);
5092+ tsk->exec_file = current->exec_file;
5093+ tsk->is_writable = current->is_writable;
5094+ if (unlikely(current->used_accept))
5095+ current->curr_ip = 0;
5096+
5097+ return;
5098+}
5099+
5100+static __inline__ void
5101+gr_set_proc_res(void)
5102+{
5103+ struct acl_subject_label *proc;
5104+ unsigned short i;
5105+
5106+ proc = current->acl;
5107+
5108+ if (proc->mode & GR_LEARN)
5109+ return;
5110+
5111+ for (i = 0; i < RLIM_NLIMITS; i++) {
5112+ if (!(proc->resmask & (1 << i)))
5113+ continue;
5114+
5115+ current->rlim[i].rlim_cur = proc->res[i].rlim_cur;
5116+ current->rlim[i].rlim_max = proc->res[i].rlim_max;
5117+ }
5118+
5119+ return;
5120+}
5121+
5122+static __inline__ void
5123+do_set_role_label(struct task_struct *task, const uid_t uid, const gid_t gid)
5124+{
5125+ task->role = lookup_acl_role_label(task, uid, gid);
5126+
5127+ return;
5128+}
5129+
5130+void
5131+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
5132+{
5133+ struct acl_object_label *obj;
5134+ struct file *filp;
5135+
5136+ if (unlikely(!(gr_status & GR_READY)))
5137+ return;
5138+
5139+ filp = task->exec_file;
5140+
5141+ /* kernel process, we'll give them the kernel role */
5142+ if (unlikely(!filp)) {
5143+ task->role = kernel_role;
5144+ task->acl = kernel_role->root_label;
5145+ return;
5146+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
5147+ do_set_role_label(task, uid, gid);
5148+
5149+ task->acl =
5150+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, task->role);
5151+
5152+ task->is_writable = 0;
5153+
5154+ /* ignore additional mmap checks for processes that are writable
5155+ by the default ACL */
5156+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
5157+ if (unlikely(obj->mode & GR_WRITE))
5158+ task->is_writable = 1;
5159+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
5160+ if (unlikely(obj->mode & GR_WRITE))
5161+ task->is_writable = 1;
5162+
5163+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
5164+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
5165+#endif
5166+
5167+ gr_set_proc_res();
5168+
5169+ return;
5170+}
5171+
5172+void
5173+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
5174+{
5175+ struct acl_subject_label *newacl;
5176+ struct acl_object_label *obj;
5177+ __u32 retmode;
5178+
5179+ if (unlikely(!(gr_status & GR_READY)))
5180+ return;
5181+
5182+ newacl = chk_subj_label(dentry, mnt, current->role);
5183+
5184+ obj = chk_obj_label(dentry, mnt, current->acl);
5185+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
5186+
5187+ if ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT)) {
5188+ if (obj->nested)
5189+ current->acl = obj->nested;
5190+ else
5191+ current->acl = newacl;
5192+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
5193+ security_audit(GR_INHERIT_ACL_MSG, current->acl->filename,
5194+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
5195+
5196+ current->is_writable = 0;
5197+
5198+ /* ignore additional mmap checks for processes that are writable
5199+ by the default ACL */
5200+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
5201+ if (unlikely(obj->mode & GR_WRITE))
5202+ current->is_writable = 1;
5203+ obj = chk_obj_label(dentry, mnt, current->role->root_label);
5204+ if (unlikely(obj->mode & GR_WRITE))
5205+ current->is_writable = 1;
5206+
5207+ gr_set_proc_res();
5208+
5209+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
5210+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", current->comm, current->pid, current->role->rolename, current->acl->filename);
5211+#endif
5212+ return;
5213+}
5214+
5215+static __inline__ void
5216+do_handle_delete(const ino_t ino, const kdev_t dev)
5217+{
5218+ struct acl_object_label *matchpo;
5219+ struct acl_subject_label *matchps;
5220+ struct acl_subject_label *i;
5221+ struct acl_role_label *role;
5222+
5223+ for (role = role_list_head; role; role = role->next) {
5224+ for (i = role->proc_subject; i; i = i->next) {
5225+ if (unlikely(i->parent_subject &&
5226+ (i->inode == ino) &&
5227+ (i->device == dev)))
5228+ i->mode |= GR_DELETED;
5229+ if (unlikely((matchpo =
5230+ lookup_acl_obj_label(ino, dev, i)) != NULL))
5231+ matchpo->mode |= GR_DELETED;
5232+ }
5233+
5234+ if (unlikely((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL))
5235+ matchps->mode |= GR_DELETED;
5236+ }
5237+
5238+ return;
5239+}
5240+
5241+void
5242+gr_handle_delete(const ino_t ino, const kdev_t dev)
5243+{
5244+ if (unlikely(!(gr_status & GR_READY)))
5245+ return;
5246+
5247+ write_lock(&gr_inode_lock);
5248+ if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
5249+ do_handle_delete(ino, dev);
5250+ write_unlock(&gr_inode_lock);
5251+
5252+ return;
5253+}
5254+
5255+static __inline__ void
5256+update_acl_obj_label(const ino_t oldinode, const kdev_t olddevice,
5257+ const ino_t newinode, const kdev_t newdevice,
5258+ struct acl_subject_label *subj)
5259+{
5260+ unsigned long index = fhash(oldinode, olddevice, subj->obj_hash_size);
5261+ struct acl_object_label **match;
5262+ struct acl_object_label *tmp;
5263+ __u8 i = 0;
5264+
5265+ match = &subj->obj_hash[index];
5266+
5267+ while (*match && ((*match)->inode != oldinode ||
5268+ (*match)->device != olddevice ||
5269+ !((*match)->mode & GR_DELETED))) {
5270+ index = (index + (1 << i)) % subj->obj_hash_size;
5271+ match = &subj->obj_hash[index];
5272+ i = (i + 1) % 32;
5273+ }
5274+
5275+ if (*match && ((*match) != deleted_object)
5276+ && ((*match)->inode == oldinode)
5277+ && ((*match)->device == olddevice)
5278+ && ((*match)->mode & GR_DELETED)) {
5279+ tmp = *match;
5280+ tmp->inode = newinode;
5281+ tmp->device = newdevice;
5282+ tmp->mode &= ~GR_DELETED;
5283+
5284+ *match = deleted_object;
5285+
5286+ insert_acl_obj_label(tmp, subj);
5287+ }
5288+
5289+ return;
5290+}
5291+
5292+static __inline__ void
5293+update_acl_subj_label(const ino_t oldinode, const kdev_t olddevice,
5294+ const ino_t newinode, const kdev_t newdevice,
5295+ struct acl_role_label *role)
5296+{
5297+ struct acl_subject_label **s_hash = role->subj_hash;
5298+ unsigned long subj_size = role->subj_hash_size;
5299+ unsigned long index = fhash(oldinode, olddevice, subj_size);
5300+ struct acl_subject_label **match;
5301+ struct acl_subject_label *tmp;
5302+ __u8 i = 0;
5303+
5304+ match = &s_hash[index];
5305+
5306+ while (*match && ((*match)->inode != oldinode ||
5307+ (*match)->device != olddevice ||
5308+ !((*match)->mode & GR_DELETED))) {
5309+ index = (index + (1 << i)) % subj_size;
5310+ i = (i + 1) % 32;
5311+ match = &s_hash[index];
5312+ }
5313+
5314+ if (*match && (*match != deleted_subject)
5315+ && ((*match)->inode == oldinode)
5316+ && ((*match)->device == olddevice)
5317+ && ((*match)->mode & GR_DELETED)) {
5318+ tmp = *match;
5319+
5320+ tmp->inode = newinode;
5321+ tmp->device = newdevice;
5322+ tmp->mode &= ~GR_DELETED;
5323+
5324+ *match = deleted_subject;
5325+
5326+ insert_acl_subj_label(tmp, role);
5327+ }
5328+
5329+ return;
5330+}
5331+
5332+static __inline__ void
5333+update_inodev_entry(const ino_t oldinode, const kdev_t olddevice,
5334+ const ino_t newinode, const kdev_t newdevice)
5335+{
5336+ unsigned long index = fhash(oldinode, olddevice, inodev_set.n_size);
5337+ struct name_entry **match;
5338+ struct name_entry *tmp;
5339+ __u8 i = 0;
5340+
5341+ match = &inodev_set.n_hash[index];
5342+
5343+ while (*match
5344+ && ((*match)->inode != oldinode
5345+ || (*match)->device != olddevice)) {
5346+ index = (index + (1 << i)) % inodev_set.n_size;
5347+ i = (i + 1) % 32;
5348+ match = &inodev_set.n_hash[index];
5349+ }
5350+
5351+ if (*match && (*match != deleted_inodev)
5352+ && ((*match)->inode == oldinode)
5353+ && ((*match)->device == olddevice)) {
5354+ tmp = *match;
5355+
5356+ tmp->inode = newinode;
5357+ tmp->device = newdevice;
5358+
5359+ *match = deleted_inodev;
5360+
5361+ insert_inodev_entry(tmp);
5362+ }
5363+
5364+ return;
5365+}
5366+
5367+static __inline__ void
5368+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
5369+ const struct vfsmount *mnt)
5370+{
5371+ struct acl_subject_label *i;
5372+ struct acl_role_label *role;
5373+
5374+ for (role = role_list_head; role; role = role->next) {
5375+ update_acl_subj_label(matchn->inode, matchn->device,
5376+ dentry->d_inode->i_ino,
5377+ dentry->d_inode->i_dev, role);
5378+
5379+ for (i = role->proc_subject; i; i = i->next) {
5380+ if (unlikely(i->parent_subject &&
5381+ (i->inode == dentry->d_inode->i_ino) &&
5382+ (i->device == dentry->d_inode->i_dev))) {
5383+ i->inode = dentry->d_inode->i_ino;
5384+ i->device = dentry->d_inode->i_dev;
5385+ }
5386+ update_acl_obj_label(matchn->inode, matchn->device,
5387+ dentry->d_inode->i_ino,
5388+ dentry->d_inode->i_dev, i);
5389+ }
5390+ }
5391+
5392+ update_inodev_entry(matchn->inode, matchn->device,
5393+ dentry->d_inode->i_ino, dentry->d_inode->i_dev);
5394+
5395+ return;
5396+}
5397+
5398+void
5399+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
5400+{
5401+ struct name_entry *matchn;
5402+
5403+ if (unlikely(!(gr_status & GR_READY)))
5404+ return;
5405+
5406+ matchn = lookup_name_entry(gr_to_filename(dentry, mnt));
5407+
5408+ if (unlikely((unsigned long)matchn)) {
5409+ write_lock(&gr_inode_lock);
5410+ do_handle_create(matchn, dentry, mnt);
5411+ write_unlock(&gr_inode_lock);
5412+ }
5413+
5414+ return;
5415+}
5416+
5417+int
5418+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
5419+ struct dentry *old_dentry,
5420+ struct dentry *new_dentry,
5421+ struct vfsmount *mnt, const __u8 replace)
5422+{
5423+ struct name_entry *matchn;
5424+ int error = 0;
5425+
5426+ matchn = lookup_name_entry(gr_to_filename(new_dentry, mnt));
5427+
5428+ lock_kernel();
5429+ error = vfs_rename(old_dir, old_dentry, new_dir, new_dentry);
5430+ unlock_kernel();
5431+
5432+ if (unlikely(error))
5433+ return error;
5434+
5435+ /* we wouldn't have to check d_inode if it weren't for
5436+ NFS silly-renaming
5437+ */
5438+
5439+ write_lock(&gr_inode_lock);
5440+ if (unlikely(replace && new_dentry->d_inode)) {
5441+ if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
5442+ new_dentry->d_inode->i_dev) &&
5443+ (old_dentry->d_inode->i_nlink <= 1)))
5444+ do_handle_delete(new_dentry->d_inode->i_ino,
5445+ new_dentry->d_inode->i_dev);
5446+ }
5447+
5448+ if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
5449+ old_dentry->d_inode->i_dev) &&
5450+ (old_dentry->d_inode->i_nlink <= 1)))
5451+ do_handle_delete(old_dentry->d_inode->i_ino,
5452+ old_dentry->d_inode->i_dev);
5453+
5454+ if (unlikely((unsigned long)matchn))
5455+ do_handle_create(matchn, old_dentry, mnt);
5456+ write_unlock(&gr_inode_lock);
5457+
5458+ return error;
5459+}
5460+
5461+static int
5462+lookup_special_role_auth(const char *rolename, unsigned char **salt,
5463+ unsigned char **sum)
5464+{
5465+ struct acl_role_label *r;
5466+ struct role_transition *trans;
5467+ __u16 i;
5468+ int found = 0;
5469+
5470+ /* check transition table */
5471+
5472+ for (trans = current->role->transitions; trans; trans = trans->next) {
5473+ if (!strcmp(rolename, trans->rolename)) {
5474+ found = 1;
5475+ break;
5476+ }
5477+ }
5478+
5479+ if (!found)
5480+ return 0;
5481+
5482+ /* handle special roles that do not require authentication */
5483+
5484+ for (r = role_list_head; r; r = r->next) {
5485+ if (!strcmp(rolename, r->rolename)
5486+ && (r->roletype & GR_ROLE_NOPW)) {
5487+ *salt = NULL;
5488+ *sum = NULL;
5489+ return 1;
5490+ }
5491+ }
5492+
5493+ for (i = 0; i < num_sprole_pws; i++) {
5494+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
5495+ *salt = acl_special_roles[i]->salt;
5496+ *sum = acl_special_roles[i]->sum;
5497+ return 1;
5498+ }
5499+ }
5500+
5501+ return 0;
5502+}
5503+
5504+static void
5505+assign_special_role(char *rolename)
5506+{
5507+ struct acl_object_label *obj;
5508+ struct acl_role_label *r;
5509+ struct acl_role_label *assigned = NULL;
5510+ struct task_struct *tsk;
5511+ struct file *filp;
5512+
5513+ for (r = role_list_head; r; r = r->next)
5514+ if (!strcmp(rolename, r->rolename) &&
5515+ (r->roletype & GR_ROLE_SPECIAL))
5516+ assigned = r;
5517+
5518+ if (!assigned)
5519+ return;
5520+
5521+ tsk = current->p_pptr;
5522+ filp = tsk->exec_file;
5523+
5524+ if (tsk && filp) {
5525+ tsk->is_writable = 0;
5526+
5527+ acl_sp_role_value = (acl_sp_role_value % 65535) + 1;
5528+ tsk->acl_sp_role = 1;
5529+ tsk->acl_role_id = acl_sp_role_value;
5530+ tsk->role = assigned;
5531+ tsk->acl =
5532+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
5533+
5534+ /* ignore additional mmap checks for processes that are writable
5535+ by the default ACL */
5536+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
5537+ if (unlikely(obj->mode & GR_WRITE))
5538+ tsk->is_writable = 1;
5539+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
5540+ if (unlikely(obj->mode & GR_WRITE))
5541+ tsk->is_writable = 1;
5542+
5543+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
5544+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
5545+#endif
5546+ }
5547+
5548+ return;
5549+}
5550+
5551+ssize_t
5552+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
5553+{
5554+ struct gr_arg *arg;
5555+ unsigned char *sprole_salt;
5556+ unsigned char *sprole_sum;
5557+ int error = sizeof (struct gr_arg);
5558+ int error2 = 0;
5559+
5560+ down(&gr_dev_sem);
5561+
5562+ arg = (struct gr_arg *) buf;
5563+
5564+ if (count != sizeof (struct gr_arg)) {
5565+ security_alert_good(GR_DEV_ACL_MSG, count,
5566+ (int) sizeof (struct gr_arg));
5567+ error = -EINVAL;
5568+ goto out;
5569+ }
5570+
5571+ if ((gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
5572+ && time_before_eq(gr_auth_expires, jiffies)) {
5573+ gr_auth_expires = 0;
5574+ gr_auth_attempts = 0;
5575+ }
5576+
5577+ if (copy_from_user(gr_usermode, arg, sizeof (struct gr_arg))) {
5578+ error = -EFAULT;
5579+ goto out;
5580+ }
5581+
5582+ if (gr_usermode->mode != SPROLE && time_after(gr_auth_expires, jiffies)) {
5583+ error = -EBUSY;
5584+ goto out;
5585+ }
5586+
5587+ /* if non-root trying to do anything other than use a special role,
5588+ do not attempt authentication, do not count towards authentication
5589+ locking
5590+ */
5591+
5592+ if (gr_usermode->mode != SPROLE && current->uid) {
5593+ error = -EPERM;
5594+ goto out;
5595+ }
5596+
5597+ /* ensure pw and special role name are null terminated */
5598+
5599+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
5600+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
5601+
5602+ /* Okay.
5603+ * We have our enough of the argument structure..(we have yet
5604+ * to copy_from_user the tables themselves) . Copy the tables
5605+ * only if we need them, i.e. for loading operations. */
5606+
5607+ switch (gr_usermode->mode) {
5608+ case STATUS:
5609+ if (gr_status & GR_READY)
5610+ error = 1;
5611+ else
5612+ error = 2;
5613+ goto out;
5614+ case SHUTDOWN:
5615+ if ((gr_status & GR_READY)
5616+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
5617+ gr_status &= ~GR_READY;
5618+ security_alert_good(GR_SHUTS_ACL_MSG, DEFAULTSECARGS);
5619+ free_variables();
5620+ memset(gr_usermode, 0, sizeof (struct gr_arg));
5621+ memset(gr_system_salt, 0, GR_SALT_LEN);
5622+ memset(gr_system_sum, 0, GR_SHA_LEN);
5623+ } else if (gr_status & GR_READY) {
5624+ security_alert(GR_SHUTF_ACL_MSG, DEFAULTSECARGS);
5625+ error = -EPERM;
5626+ } else {
5627+ security_alert_good(GR_SHUTI_ACL_MSG, DEFAULTSECARGS);
5628+ error = -EAGAIN;
5629+ }
5630+ break;
5631+ case ENABLE:
5632+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
5633+ security_alert_good(GR_ENABLE_ACL_MSG, GR_VERSION);
5634+ else {
5635+ if (gr_status & GR_READY)
5636+ error = -EAGAIN;
5637+ else
5638+ error = error2;
5639+ security_alert(GR_ENABLEF_ACL_MSG, GR_VERSION,
5640+ DEFAULTSECARGS);
5641+ }
5642+ break;
5643+ case RELOAD:
5644+ if (!(gr_status & GR_READY)) {
5645+ security_alert_good(GR_RELOADI_ACL_MSG);
5646+ error = -EAGAIN;
5647+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
5648+ lock_kernel();
5649+ gr_status &= ~GR_READY;
5650+ free_variables();
5651+ if (!(error2 = gracl_init(gr_usermode))) {
5652+ unlock_kernel();
5653+ security_alert_good(GR_RELOAD_ACL_MSG,
5654+ GR_VERSION);
5655+ } else {
5656+ unlock_kernel();
5657+ error = error2;
5658+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
5659+ DEFAULTSECARGS);
5660+ }
5661+ } else {
5662+ security_alert(GR_RELOADF_ACL_MSG, GR_VERSION,
5663+ DEFAULTSECARGS);
5664+ error = -EPERM;
5665+ }
5666+ break;
5667+ case SEGVMOD:
5668+ if (unlikely(!(gr_status & GR_READY))) {
5669+ security_alert_good(GR_SEGVMODI_ACL_MSG,
5670+ DEFAULTSECARGS);
5671+ error = -EAGAIN;
5672+ break;
5673+ }
5674+
5675+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
5676+ security_alert_good(GR_SEGVMODS_ACL_MSG,
5677+ DEFAULTSECARGS);
5678+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
5679+ struct acl_subject_label *segvacl;
5680+ segvacl =
5681+ lookup_acl_subj_label(gr_usermode->segv_inode,
5682+ gr_usermode->segv_device,
5683+ current->role);
5684+ if (segvacl) {
5685+ segvacl->crashes = 0;
5686+ segvacl->expires = 0;
5687+ }
5688+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
5689+ gr_remove_uid(gr_usermode->segv_uid);
5690+ }
5691+ } else {
5692+ security_alert(GR_SEGVMODF_ACL_MSG, DEFAULTSECARGS);
5693+ error = -EPERM;
5694+ }
5695+ break;
5696+ case SPROLE:
5697+ if (unlikely(!(gr_status & GR_READY))) {
5698+ security_alert_good(GR_SPROLEI_ACL_MSG, DEFAULTSECARGS);
5699+ error = -EAGAIN;
5700+ break;
5701+ }
5702+
5703+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
5704+ && time_before_eq(current->role->expires, jiffies)) {
5705+ current->role->expires = 0;
5706+ current->role->auth_attempts = 0;
5707+ }
5708+
5709+ if (time_after(current->role->expires, jiffies)) {
5710+ error = -EBUSY;
5711+ goto out;
5712+ }
5713+
5714+ if (lookup_special_role_auth
5715+ (gr_usermode->sp_role, &sprole_salt, &sprole_sum)
5716+ && ((!sprole_salt && !sprole_sum)
5717+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
5718+ assign_special_role(gr_usermode->sp_role);
5719+ security_alert_good(GR_SPROLES_ACL_MSG,
5720+ (current->p_pptr) ? current->
5721+ p_pptr->role->rolename : "",
5722+ acl_sp_role_value, DEFAULTSECARGS);
5723+ } else {
5724+ security_alert(GR_SPROLEF_ACL_MSG, gr_usermode->sp_role,
5725+ DEFAULTSECARGS);
5726+ error = -EPERM;
5727+ current->role->auth_attempts++;
5728+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
5729+ current->role->expires =
5730+ jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
5731+ security_alert(GR_MAXROLEPW_ACL_MSG,
5732+ CONFIG_GRKERNSEC_ACL_MAXTRIES,
5733+ gr_usermode->sp_role, DEFAULTSECARGS);
5734+ }
5735+
5736+ goto out;
5737+ }
5738+ break;
5739+ case UNSPROLE:
5740+ if (unlikely(!(gr_status & GR_READY))) {
5741+ security_alert_good(GR_UNSPROLEI_ACL_MSG, DEFAULTSECARGS);
5742+ error = -EAGAIN;
5743+ break;
5744+ }
5745+
5746+ if ((current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES)
5747+ && time_before_eq(current->role->expires, jiffies)) {
5748+ current->role->expires = 0;
5749+ current->role->auth_attempts = 0;
5750+ }
5751+
5752+ if (time_after(current->role->expires, jiffies)) {
5753+ error = -EBUSY;
5754+ goto out;
5755+ }
5756+
5757+ if ((current->role->roletype & GR_ROLE_SPECIAL) &&
5758+ lookup_special_role_auth
5759+ (current->role->rolename, &sprole_salt, &sprole_sum)
5760+ && ((!sprole_salt && !sprole_sum)
5761+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
5762+ security_alert_good(GR_UNSPROLES_ACL_MSG,
5763+ (current->p_pptr) ? current->
5764+ p_pptr->role->rolename : "",
5765+ (current->p_pptr) ? current->
5766+ p_pptr->acl_role_id : 0, DEFAULTSECARGS);
5767+ gr_set_acls(1);
5768+ if (current->p_pptr)
5769+ current->p_pptr->acl_sp_role = 0;
5770+ } else {
5771+ security_alert(GR_UNSPROLEF_ACL_MSG, gr_usermode->sp_role,
5772+ DEFAULTSECARGS);
5773+ error = -EPERM;
5774+ current->role->auth_attempts++;
5775+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
5776+ current->role->expires =
5777+ jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
5778+ security_alert(GR_MAXROLEPW_ACL_MSG,
5779+ CONFIG_GRKERNSEC_ACL_MAXTRIES,
5780+ current->role->rolename, DEFAULTSECARGS);
5781+ }
5782+
5783+ goto out;
5784+ }
5785+ break;
5786+ default:
5787+ security_alert(GR_INVMODE_ACL_MSG, gr_usermode->mode,
5788+ DEFAULTSECARGS);
5789+ error = -EINVAL;
5790+ break;
5791+ }
5792+
5793+ if (error != -EPERM)
5794+ goto out;
5795+
5796+ gr_auth_attempts++;
5797+
5798+ if (gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES) {
5799+ security_alert(GR_MAXPW_ACL_MSG, CONFIG_GRKERNSEC_ACL_MAXTRIES);
5800+ gr_auth_expires = jiffies + CONFIG_GRKERNSEC_ACL_TIMEOUT * HZ;
5801+ }
5802+
5803+ out:
5804+ up(&gr_dev_sem);
5805+ return error;
5806+}
5807+
5808+int
5809+gr_set_acls(const int type)
5810+{
5811+ struct acl_object_label *obj;
5812+ struct task_struct *task;
5813+ struct file *filp;
5814+ unsigned short i;
5815+
5816+ read_lock(&tasklist_lock);
5817+ for_each_task(task) {
5818+ /* check to see if we're called from the exit handler,
5819+ if so, only replace ACLs that have inherited the admin
5820+ ACL */
5821+
5822+ if (type && (task->role != current->role ||
5823+ task->acl_role_id != current->acl_role_id))
5824+ continue;
5825+
5826+ task->acl_role_id = 0;
5827+
5828+ if ((filp = task->exec_file)) {
5829+ do_set_role_label(task, task->uid, task->gid);
5830+
5831+ task->acl =
5832+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
5833+ task->role);
5834+ if (task->acl) {
5835+ struct acl_subject_label *curr;
5836+ curr = task->acl;
5837+
5838+ task->is_writable = 0;
5839+ /* ignore additional mmap checks for processes that are writable
5840+ by the default ACL */
5841+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
5842+ if (unlikely(obj->mode & GR_WRITE))
5843+ task->is_writable = 1;
5844+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
5845+ if (unlikely(obj->mode & GR_WRITE))
5846+ task->is_writable = 1;
5847+
5848+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
5849+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
5850+#endif
5851+ if (!(curr->mode & GR_LEARN))
5852+ for (i = 0; i < RLIM_NLIMITS; i++) {
5853+ if (!(curr->resmask & (1 << i)))
5854+ continue;
5855+
5856+ task->rlim[i].rlim_cur =
5857+ curr->res[i].rlim_cur;
5858+ task->rlim[i].rlim_max =
5859+ curr->res[i].rlim_max;
5860+ }
5861+ } else {
5862+ read_unlock(&tasklist_lock);
5863+ security_alert_good(GR_DEFACL_MSG, task->comm,
5864+ task->pid);
5865+ return 1;
5866+ }
5867+ } else {
5868+ // it's a kernel process
5869+ task->role = kernel_role;
5870+ task->acl = kernel_role->root_label;
5871+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
5872+ task->acl->mode &= ~GR_FIND;
5873+#endif
5874+ }
5875+ }
5876+ read_unlock(&tasklist_lock);
5877+ return 0;
5878+}
5879+
5880+void
5881+gr_learn_resource(const struct task_struct *task,
5882+ const int res, const unsigned long wanted)
5883+{
5884+ struct acl_subject_label *acl;
5885+
5886+ if (unlikely((gr_status & GR_READY) &&
5887+ task->acl && (task->acl->mode & GR_LEARN)))
5888+ goto skip_reslog;
5889+
5890+#ifdef CONFIG_GRKERNSEC_RESLOG
5891+ gr_log_resource(task, res, wanted);
5892+#endif
5893+ skip_reslog:
5894+
5895+ if (unlikely(!(gr_status & GR_READY) || !wanted))
5896+ return;
5897+
5898+ acl = task->acl;
5899+
5900+ if (likely(!acl || !(acl->mode & GR_LEARN) ||
5901+ !(acl->resmask & (1 << (unsigned short) res))))
5902+ return;
5903+
5904+ if (wanted >= acl->res[res].rlim_cur) {
5905+ unsigned long res_add;
5906+
5907+ res_add = wanted;
5908+ switch (res) {
5909+ case RLIMIT_CPU:
5910+ res_add += GR_RLIM_CPU_BUMP;
5911+ break;
5912+ case RLIMIT_FSIZE:
5913+ res_add += GR_RLIM_FSIZE_BUMP;
5914+ break;
5915+ case RLIMIT_DATA:
5916+ res_add += GR_RLIM_DATA_BUMP;
5917+ break;
5918+ case RLIMIT_STACK:
5919+ res_add += GR_RLIM_STACK_BUMP;
5920+ break;
5921+ case RLIMIT_CORE:
5922+ res_add += GR_RLIM_CORE_BUMP;
5923+ break;
5924+ case RLIMIT_RSS:
5925+ res_add += GR_RLIM_RSS_BUMP;
5926+ break;
5927+ case RLIMIT_NPROC:
5928+ res_add += GR_RLIM_NPROC_BUMP;
5929+ break;
5930+ case RLIMIT_NOFILE:
5931+ res_add += GR_RLIM_NOFILE_BUMP;
5932+ break;
5933+ case RLIMIT_MEMLOCK:
5934+ res_add += GR_RLIM_MEMLOCK_BUMP;
5935+ break;
5936+ case RLIMIT_AS:
5937+ res_add += GR_RLIM_AS_BUMP;
5938+ break;
5939+ case RLIMIT_LOCKS:
5940+ res_add += GR_RLIM_LOCKS_BUMP;
5941+ break;
5942+ }
5943+
5944+ acl->res[res].rlim_cur = res_add;
5945+
5946+ if (wanted > acl->res[res].rlim_max)
5947+ acl->res[res].rlim_max = res_add;
5948+
5949+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
5950+ current->role->roletype, acl->filename,
5951+ acl->res[res].rlim_cur, acl->res[res].rlim_max,
5952+ "", (unsigned long) res);
5953+ }
5954+
5955+ return;
5956+}
5957+
5958+#ifdef CONFIG_SYSCTL
5959+extern struct proc_dir_entry *proc_sys_root;
5960+
5961+__u32
5962+gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
5963+ const void *newval)
5964+{
5965+ struct proc_dir_entry *tmp;
5966+ struct nameidata nd;
5967+ const char *proc_sys = "/proc/sys";
5968+ char *path = gr_shared_page[0][smp_processor_id()];
5969+ struct acl_object_label *obj;
5970+ unsigned short len = 0, pos = 0, depth = 0, i;
5971+ __u32 err = 0;
5972+ __u32 mode = 0;
5973+
5974+ if (unlikely(!(gr_status & GR_READY)))
5975+ return 1;
5976+
5977+ if (oldval)
5978+ mode |= GR_READ;
5979+ if (newval)
5980+ mode |= GR_WRITE;
5981+
5982+ /* convert the requested sysctl entry into a pathname */
5983+
5984+ for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
5985+ len += strlen(tmp->name);
5986+ len++;
5987+ depth++;
5988+ }
5989+
5990+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
5991+ return 0; // deny
5992+
5993+ memset(path, 0, PAGE_SIZE);
5994+
5995+ memcpy(path, proc_sys, strlen(proc_sys));
5996+
5997+ pos += strlen(proc_sys);
5998+
5999+ for (; depth > 0; depth--) {
6000+ path[pos] = '/';
6001+ pos++;
6002+ for (i = 1, tmp = table->de; tmp != proc_sys_root;
6003+ tmp = tmp->parent) {
6004+ if (depth == i) {
6005+ memcpy(path + pos, tmp->name,
6006+ strlen(tmp->name));
6007+ pos += strlen(tmp->name);
6008+ }
6009+ i++;
6010+ }
6011+ }
6012+
6013+ if (path_init(path, LOOKUP_FOLLOW, &nd))
6014+ err = path_walk(path, &nd);
6015+
6016+ if (err)
6017+ goto out;
6018+
6019+ obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
6020+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
6021+
6022+ if (unlikely((current->acl->mode & GR_LEARN) && ((err & mode) != mode))) {
6023+ __u32 new_mode = mode;
6024+
6025+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
6026+
6027+ err = new_mode;
6028+ gr_log_learn(current->role, current->uid, current->gid,
6029+ current, path, new_mode);
6030+ } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
6031+ security_alert(GR_SYSCTL_ACL_MSG, "denied", path,
6032+ (mode & GR_READ) ? " reading" : "",
6033+ (mode & GR_WRITE) ? " writing" : "",
6034+ DEFAULTSECARGS);
6035+ err = 0;
6036+ } else if ((err & mode) != mode) {
6037+ err = 0;
6038+ } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
6039+ security_audit(GR_SYSCTL_ACL_MSG, "successful",
6040+ path, (mode & GR_READ) ? " reading" : "",
6041+ (mode & GR_WRITE) ? " writing" : "",
6042+ DEFAULTSECARGS);
6043+ }
6044+
6045+ path_release(&nd);
6046+
6047+ out:
6048+ return err;
6049+}
6050+#endif
6051+
6052+int
6053+gr_handle_ptrace(struct task_struct *task, const long request)
6054+{
6055+ struct file *filp;
6056+ __u32 retmode;
6057+
6058+ if (unlikely(!(gr_status & GR_READY)))
6059+ return 0;
6060+
6061+ filp = task->exec_file;
6062+
6063+ if (unlikely(!filp))
6064+ return 0;
6065+
6066+ retmode = gr_search_file(filp->f_dentry, GR_PTRACERD, filp->f_vfsmnt);
6067+
6068+ if (retmode & GR_PTRACERD) {
6069+ switch (request) {
6070+ case PTRACE_POKETEXT:
6071+ case PTRACE_POKEDATA:
6072+ case PTRACE_POKEUSR:
6073+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA)
6074+ case PTRACE_SETREGS:
6075+ case PTRACE_SETFPREGS:
6076+#endif
6077+#ifdef CONFIG_X86
6078+ case PTRACE_SETFPXREGS:
6079+#endif
6080+#ifdef CONFIG_ALTIVEC
6081+ case PTRACE_SETVRREGS:
6082+#endif
6083+ return 1;
6084+ default:
6085+ return 0;
6086+ }
6087+ } else if (!(current->acl->mode & GR_OVERRIDE) &&
6088+ !(current->role->roletype & GR_ROLE_GOD)
6089+ && (current->acl != task->acl
6090+ || (current->acl != current->role->root_label
6091+ && current->pid != task->pid))) {
6092+ security_alert(GR_PTRACE_ACL_MSG,
6093+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
6094+ task->comm, task->pid, DEFAULTSECARGS);
6095+ return 1;
6096+ }
6097+
6098+ return 0;
6099+}
6100+
6101+int
6102+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
6103+{
6104+ __u32 retmode;
6105+ struct acl_subject_label *subj;
6106+
6107+ if (unlikely(!(gr_status & GR_READY)))
6108+ return 0;
6109+
6110+ if (unlikely
6111+ ((current->ptrace & PT_PTRACED)
6112+ && !(current->acl->mode & GR_OVERRIDE)))
6113+ retmode = gr_search_file(dentry, GR_PTRACERD, mnt);
6114+ else
6115+ return 0;
6116+
6117+ subj = chk_subj_label(dentry, mnt, current->role);
6118+
6119+ if (!(retmode & GR_PTRACERD) &&
6120+ !(current->role->roletype & GR_ROLE_GOD) &&
6121+ (current->acl != subj)) {
6122+ security_alert(GR_PTRACE_EXEC_ACL_MSG,
6123+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
6124+ return 1;
6125+ }
6126+
6127+ return 0;
6128+}
6129+
6130+int
6131+gr_handle_mmap(const struct file *filp, const unsigned long prot)
6132+{
6133+ struct acl_object_label *obj, *obj2;
6134+
6135+ if (unlikely(!(gr_status & GR_READY) ||
6136+ (current->acl->mode & GR_OVERRIDE) || !filp ||
6137+ !(prot & PROT_EXEC)))
6138+ return 0;
6139+
6140+ if (unlikely(current->is_writable))
6141+ return 0;
6142+
6143+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
6144+ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
6145+ current->role->root_label);
6146+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
6147+ security_alert(GR_WRITLIB_ACL_MSG,
6148+ gr_to_filename(filp->f_dentry, filp->f_vfsmnt),
6149+ DEFAULTSECARGS);
6150+ return 1;
6151+ }
6152+
6153+ return 0;
6154+}
6155+
6156+int
6157+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
6158+{
6159+ __u32 mode;
6160+
6161+ if (unlikely(!file || !(prot & PROT_EXEC)))
6162+ return 1;
6163+
6164+ mode =
6165+ gr_search_file(file->f_dentry,
6166+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
6167+ file->f_vfsmnt);
6168+
6169+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
6170+ security_alert(GR_MMAP_ACL_MSG, "denied",
6171+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
6172+ DEFAULTSECARGS);
6173+ return 0;
6174+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
6175+ return 0;
6176+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
6177+ security_audit(GR_MMAP_ACL_MSG, "successful",
6178+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
6179+ DEFAULTSECARGS);
6180+ return 1;
6181+ }
6182+
6183+ return 1;
6184+}
6185+
6186+int
6187+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
6188+{
6189+ __u32 mode;
6190+
6191+ if (unlikely(!file || !(prot & PROT_EXEC)))
6192+ return 1;
6193+
6194+ mode =
6195+ gr_search_file(file->f_dentry,
6196+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
6197+ file->f_vfsmnt);
6198+
6199+ if (unlikely(!gr_tpe_allow(file) || (!(mode & GR_EXEC) && !(mode & GR_SUPPRESS)))) {
6200+ security_alert(GR_MPROTECT_ACL_MSG, "denied",
6201+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
6202+ DEFAULTSECARGS);
6203+ return 0;
6204+ } else if (unlikely(!gr_tpe_allow(file) || !(mode & GR_EXEC))) {
6205+ return 0;
6206+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
6207+ security_audit(GR_MPROTECT_ACL_MSG, "successful",
6208+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
6209+ DEFAULTSECARGS);
6210+ return 1;
6211+ }
6212+
6213+ return 1;
6214+}
6215+
6216+void
6217+gr_acl_handle_psacct(struct task_struct *task, const long code)
6218+{
6219+ unsigned long runtime;
6220+ unsigned long cputime;
6221+ unsigned int wday, cday;
6222+ __u8 whr, chr;
6223+ __u8 wmin, cmin;
6224+ __u8 wsec, csec;
6225+ char cur_tty[64] = { 0 };
6226+ char parent_tty[64] = { 0 };
6227+
6228+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
6229+ !(task->acl->mode & GR_PROCACCT)))
6230+ return;
6231+
6232+ runtime = (jiffies - task->start_time) / HZ;
6233+ wday = runtime / (3600 * 24);
6234+ runtime -= wday * (3600 * 24);
6235+ whr = runtime / 3600;
6236+ runtime -= whr * 3600;
6237+ wmin = runtime / 60;
6238+ runtime -= wmin * 60;
6239+ wsec = runtime;
6240+
6241+ cputime = (task->times.tms_utime + task->times.tms_stime) / HZ;
6242+ cday = cputime / (3600 * 24);
6243+ cputime -= cday * (3600 * 24);
6244+ chr = cputime / 3600;
6245+ cputime -= chr * 3600;
6246+ cmin = cputime / 60;
6247+ cputime -= cmin * 60;
6248+ csec = cputime;
6249+
6250+ security_audit(GR_ACL_PROCACCT_MSG, gr_task_fullpath(task), task->comm,
6251+ task->pid, NIPQUAD(task->curr_ip), tty_name(task->tty,
6252+ cur_tty),
6253+ task->uid, task->euid, task->gid, task->egid, wday, whr,
6254+ wmin, wsec, cday, chr, cmin, csec,
6255+ (task->
6256+ flags & PF_SIGNALED) ? "killed by signal" : "exited",
6257+ code, gr_parent_task_fullpath(task),
6258+ task->p_pptr->comm, task->p_pptr->pid,
6259+ NIPQUAD(task->p_pptr->curr_ip),
6260+ tty_name(task->p_pptr->tty, parent_tty),
6261+ task->p_pptr->uid, task->p_pptr->euid, task->p_pptr->gid,
6262+ task->p_pptr->egid);
6263+
6264+ return;
6265+}
6266+
6267+void gr_set_kernel_label(struct task_struct *task)
6268+{
6269+ if (gr_status & GR_READY) {
6270+ task->role = kernel_role;
6271+ task->acl = kernel_role->root_label;
6272+ }
6273+ return;
6274+}
6275diff -urN linux-2.4.22/grsecurity/gracl_alloc.c linux-2.4.22/grsecurity/gracl_alloc.c
6276--- linux-2.4.22/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
6277+++ linux-2.4.22/grsecurity/gracl_alloc.c 2003-09-02 19:29:42.000000000 -0400
6278@@ -0,0 +1,94 @@
6279+/* stack-based acl allocation tracking (c) Brad Spengler 2002,2003 */
6280+
6281+#include <linux/kernel.h>
6282+#include <linux/mm.h>
6283+#include <linux/slab.h>
6284+#include <linux/vmalloc.h>
6285+#include <linux/gracl.h>
6286+#include <linux/grsecurity.h>
6287+
6288+static unsigned long alloc_stack_next = 1;
6289+static unsigned long alloc_stack_size = 1;
6290+static void **alloc_stack;
6291+
6292+static __inline__ int
6293+alloc_pop(void)
6294+{
6295+ if ((alloc_stack_next - 1) == 0)
6296+ return 0;
6297+
6298+ if (*(alloc_stack + alloc_stack_next - 2))
6299+ kfree(*(alloc_stack + alloc_stack_next - 2));
6300+
6301+ alloc_stack_next--;
6302+
6303+ return 1;
6304+}
6305+
6306+static __inline__ void
6307+alloc_push(void *buf)
6308+{
6309+ if (alloc_stack_next >= alloc_stack_size)
6310+ BUG();
6311+
6312+ *(alloc_stack + alloc_stack_next - 1) = buf;
6313+
6314+ alloc_stack_next++;
6315+
6316+ return;
6317+}
6318+
6319+void *
6320+acl_alloc(unsigned long len)
6321+{
6322+ void *ret;
6323+
6324+ if (len > PAGE_SIZE)
6325+ BUG();
6326+
6327+ ret = kmalloc(len, GFP_KERNEL);
6328+
6329+ if (ret)
6330+ alloc_push(ret);
6331+
6332+ return ret;
6333+}
6334+
6335+void
6336+acl_free_all(void)
6337+{
6338+ if (gr_acl_is_enabled() || !alloc_stack)
6339+ return;
6340+
6341+ while (alloc_pop()) ;
6342+
6343+ if (alloc_stack) {
6344+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
6345+ kfree(alloc_stack);
6346+ else
6347+ vfree(alloc_stack);
6348+ }
6349+
6350+ alloc_stack = NULL;
6351+ alloc_stack_size = 1;
6352+ alloc_stack_next = 1;
6353+
6354+ return;
6355+}
6356+
6357+int
6358+acl_alloc_stack_init(unsigned long size)
6359+{
6360+ if ((size * sizeof (void *)) <= PAGE_SIZE)
6361+ alloc_stack =
6362+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
6363+ else
6364+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
6365+
6366+ alloc_stack_size = size;
6367+
6368+ if (!alloc_stack)
6369+ return 0;
6370+ else
6371+ return 1;
6372+}
6373diff -urN linux-2.4.22/grsecurity/gracl_cap.c linux-2.4.22/grsecurity/gracl_cap.c
6374--- linux-2.4.22/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
6375+++ linux-2.4.22/grsecurity/gracl_cap.c 2003-09-02 19:29:42.000000000 -0400
6376@@ -0,0 +1,71 @@
6377+/* capability handling routines, (c) Brad Spengler 2002,2003 */
6378+
6379+#include <linux/kernel.h>
6380+#include <linux/sched.h>
6381+#include <linux/capability.h>
6382+#include <linux/gracl.h>
6383+#include <linux/grsecurity.h>
6384+#include <linux/grinternal.h>
6385+
6386+static const char *captab_log[29] = {
6387+ "CAP_CHOWN",
6388+ "CAP_DAC_OVERRIDE",
6389+ "CAP_DAC_READ_SEARCH",
6390+ "CAP_FOWNER",
6391+ "CAP_FSETID",
6392+ "CAP_KILL",
6393+ "CAP_SETGID",
6394+ "CAP_SETUID",
6395+ "CAP_SETPCAP",
6396+ "CAP_LINUX_IMMUTABLE",
6397+ "CAP_NET_BIND_SERVICE",
6398+ "CAP_NET_BROADCAST",
6399+ "CAP_NET_ADMIN",
6400+ "CAP_NET_RAW",
6401+ "CAP_IPC_LOCK",
6402+ "CAP_IPC_OWNER",
6403+ "CAP_SYS_MODULE",
6404+ "CAP_SYS_RAWIO",
6405+ "CAP_SYS_CHROOT",
6406+ "CAP_SYS_PTRACE",
6407+ "CAP_SYS_PACCT",
6408+ "CAP_SYS_ADMIN",
6409+ "CAP_SYS_BOOT",
6410+ "CAP_SYS_NICE",
6411+ "CAP_SYS_RESOURCE",
6412+ "CAP_SYS_TIME",
6413+ "CAP_SYS_TTY_CONFIG",
6414+ "CAP_MKNOD",
6415+ "CAP_LEASE"
6416+};
6417+
6418+int
6419+gr_is_capable(const int cap)
6420+{
6421+ struct acl_subject_label *curracl;
6422+
6423+ if (!gr_acl_is_enabled())
6424+ return 1;
6425+
6426+ curracl = current->acl;
6427+
6428+ if (!cap_raised(curracl->cap_lower, cap))
6429+ return 1;
6430+
6431+ if ((curracl->mode & GR_LEARN)
6432+ && cap_raised(current->cap_effective, cap)) {
6433+ security_learn(GR_LEARN_AUDIT_MSG, current->role->rolename,
6434+ current->role->roletype, current->uid,
6435+ current->gid, current->exec_file ?
6436+ gr_to_filename(current->exec_file->f_dentry,
6437+ current->exec_file->f_vfsmnt) : curracl->filename,
6438+ curracl->filename, 0UL,
6439+ 0UL, "", (unsigned long) cap, NIPQUAD(current->curr_ip));
6440+ return 1;
6441+ }
6442+
6443+ if ((cap >= 0) && (cap < 29) && cap_raised(current->cap_effective, cap))
6444+ security_alert(GR_CAP_ACL_MSG, captab_log[cap], DEFAULTSECARGS);
6445+
6446+ return 0;
6447+}
6448diff -urN linux-2.4.22/grsecurity/gracl_fs.c linux-2.4.22/grsecurity/gracl_fs.c
6449--- linux-2.4.22/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
6450+++ linux-2.4.22/grsecurity/gracl_fs.c 2003-09-02 19:29:42.000000000 -0400
6451@@ -0,0 +1,469 @@
6452+#include <linux/kernel.h>
6453+#include <linux/sched.h>
6454+#include <linux/types.h>
6455+#include <linux/fs.h>
6456+#include <linux/file.h>
6457+#include <linux/grsecurity.h>
6458+#include <linux/grinternal.h>
6459+#include <linux/gracl.h>
6460+
6461+__u32
6462+gr_acl_handle_hidden_file(const struct dentry * dentry,
6463+ const struct vfsmount * mnt)
6464+{
6465+ __u32 mode;
6466+
6467+ if (unlikely(!dentry->d_inode))
6468+ return GR_FIND;
6469+
6470+ mode =
6471+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
6472+
6473+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
6474+ security_audit(GR_HIDDEN_ACL_MSG, "successful",
6475+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
6476+ return mode;
6477+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
6478+ security_alert(GR_HIDDEN_ACL_MSG, "denied",
6479+ gr_to_filename(dentry, mnt),
6480+ DEFAULTSECARGS);
6481+ return 0;
6482+ } else if (unlikely(!(mode & GR_FIND)))
6483+ return 0;
6484+
6485+ return GR_FIND;
6486+}
6487+
6488+__u32
6489+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
6490+ const int fmode)
6491+{
6492+ __u32 reqmode = GR_FIND;
6493+ __u32 mode;
6494+
6495+ if (unlikely(!dentry->d_inode))
6496+ return reqmode;
6497+
6498+ if (unlikely(fmode & O_APPEND))
6499+ reqmode |= GR_APPEND;
6500+ else if (unlikely(fmode & FMODE_WRITE))
6501+ reqmode |= GR_WRITE;
6502+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
6503+ reqmode |= GR_READ;
6504+
6505+ mode =
6506+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
6507+ mnt);
6508+
6509+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
6510+ security_audit(GR_OPEN_ACL_MSG, "successful",
6511+ gr_to_filename(dentry, mnt),
6512+ reqmode & GR_READ ? " reading" : "",
6513+ reqmode & GR_WRITE ? " writing" :
6514+ reqmode & GR_APPEND ? " appending" : "",
6515+ DEFAULTSECARGS);
6516+ return reqmode;
6517+ } else
6518+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
6519+ {
6520+ security_alert(GR_OPEN_ACL_MSG, "denied",
6521+ gr_to_filename(dentry, mnt),
6522+ reqmode & GR_READ ? " reading" : "",
6523+ reqmode & GR_WRITE ? " writing" : reqmode &
6524+ GR_APPEND ? " appending" : "", DEFAULTSECARGS);
6525+ return 0;
6526+ } else if (unlikely((mode & reqmode) != reqmode))
6527+ return 0;
6528+
6529+ return reqmode;
6530+}
6531+
6532+__u32
6533+gr_acl_handle_creat(const struct dentry * dentry,
6534+ const struct dentry * p_dentry,
6535+ const struct vfsmount * p_mnt, const int fmode,
6536+ const int imode)
6537+{
6538+ __u32 reqmode = GR_WRITE | GR_CREATE;
6539+ __u32 mode;
6540+
6541+ if (unlikely(fmode & O_APPEND))
6542+ reqmode |= GR_APPEND;
6543+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
6544+ reqmode |= GR_READ;
6545+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
6546+ reqmode |= GR_SETID;
6547+
6548+ mode =
6549+ gr_check_create(dentry, p_dentry, p_mnt,
6550+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
6551+
6552+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
6553+ security_audit(GR_CREATE_ACL_MSG, "successful",
6554+ gr_to_filename(dentry, p_mnt),
6555+ reqmode & GR_READ ? " reading" : "",
6556+ reqmode & GR_WRITE ? " writing" :
6557+ reqmode & GR_APPEND ? " appending" : "",
6558+ DEFAULTSECARGS);
6559+ return reqmode;
6560+ } else
6561+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
6562+ {
6563+ security_alert(GR_CREATE_ACL_MSG, "denied",
6564+ gr_to_filename(dentry, p_mnt),
6565+ reqmode & GR_READ ? " reading" : "",
6566+ reqmode & GR_WRITE ? " writing" : reqmode &
6567+ GR_APPEND ? " appending" : "", DEFAULTSECARGS);
6568+ return 0;
6569+ } else if (unlikely((mode & reqmode) != reqmode))
6570+ return 0;
6571+
6572+ return reqmode;
6573+}
6574+
6575+__u32
6576+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
6577+ const int fmode)
6578+{
6579+ __u32 mode, reqmode = GR_FIND;
6580+
6581+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
6582+ reqmode |= GR_EXEC;
6583+ if (fmode & S_IWOTH)
6584+ reqmode |= GR_WRITE;
6585+ if (fmode & S_IROTH)
6586+ reqmode |= GR_READ;
6587+
6588+ mode =
6589+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
6590+ mnt);
6591+
6592+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
6593+ security_audit(GR_ACCESS_ACL_MSG, "successful",
6594+ gr_to_filename(dentry, mnt),
6595+ reqmode & GR_READ ? " reading" : "",
6596+ reqmode & GR_WRITE ? " writing" : "",
6597+ reqmode & GR_EXEC ? " executing" : "",
6598+ DEFAULTSECARGS);
6599+ return reqmode;
6600+ } else
6601+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
6602+ {
6603+ security_alert(GR_ACCESS_ACL_MSG, "denied",
6604+ gr_to_filename(dentry, mnt),
6605+ reqmode & GR_READ ? " reading" : "",
6606+ reqmode & GR_WRITE ? " writing" : "",
6607+ reqmode & GR_EXEC ? " executing" : "",
6608+ DEFAULTSECARGS);
6609+ return 0;
6610+ } else if (unlikely((mode & reqmode) != reqmode))
6611+ return 0;
6612+
6613+ return reqmode;
6614+}
6615+
6616+#define generic_fs_handler(dentry, mnt, reqmode, fmt) \
6617+{ \
6618+ __u32 mode; \
6619+ \
6620+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt); \
6621+ \
6622+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
6623+ security_audit(fmt, "successful", \
6624+ gr_to_filename(dentry, mnt), DEFAULTSECARGS); \
6625+ return mode; \
6626+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
6627+ security_alert(fmt, "denied", gr_to_filename(dentry, mnt), \
6628+ DEFAULTSECARGS); \
6629+ return 0; \
6630+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \
6631+ return 0; \
6632+ \
6633+ return (reqmode); \
6634+}
6635+
6636+__u32
6637+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
6638+{
6639+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
6640+}
6641+
6642+__u32
6643+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
6644+{
6645+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
6646+}
6647+
6648+__u32
6649+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
6650+{
6651+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
6652+}
6653+
6654+__u32
6655+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
6656+{
6657+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
6658+}
6659+
6660+__u32
6661+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
6662+ mode_t mode)
6663+{
6664+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
6665+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
6666+ GR_FCHMOD_ACL_MSG);
6667+ } else {
6668+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
6669+ }
6670+}
6671+
6672+__u32
6673+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
6674+ mode_t mode)
6675+{
6676+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
6677+ generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
6678+ GR_CHMOD_ACL_MSG);
6679+ } else {
6680+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
6681+ }
6682+}
6683+
6684+__u32
6685+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
6686+{
6687+ generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
6688+}
6689+
6690+__u32
6691+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
6692+{
6693+ generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
6694+}
6695+
6696+__u32
6697+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
6698+{
6699+ generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
6700+ GR_UNIXCONNECT_ACL_MSG);
6701+}
6702+
6703+__u32
6704+gr_acl_handle_filldir(const struct dentry *dentry, const struct vfsmount *mnt,
6705+ const ino_t ino)
6706+{
6707+ if (likely((unsigned long)(dentry->d_inode))) {
6708+ struct dentry d = *dentry;
6709+ struct inode inode = *(dentry->d_inode);
6710+
6711+ inode.i_ino = ino;
6712+ d.d_inode = &inode;
6713+
6714+ if (unlikely(!gr_search_file(&d, GR_FIND | GR_NOLEARN, mnt)))
6715+ return 0;
6716+ }
6717+
6718+ return 1;
6719+}
6720+
6721+__u32
6722+gr_acl_handle_link(const struct dentry * new_dentry,
6723+ const struct dentry * parent_dentry,
6724+ const struct vfsmount * parent_mnt,
6725+ const struct dentry * old_dentry,
6726+ const struct vfsmount * old_mnt, const char *to)
6727+{
6728+ __u32 needmode = GR_WRITE | GR_CREATE;
6729+ __u32 mode;
6730+
6731+ mode =
6732+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
6733+ old_mnt);
6734+
6735+ if (unlikely(((mode & needmode) == needmode) && mode & GR_AUDITS)) {
6736+ security_audit(GR_LINK_ACL_MSG, "successful",
6737+ gr_to_filename(old_dentry, old_mnt), to,
6738+ DEFAULTSECARGS);
6739+ return mode;
6740+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
6741+ security_alert(GR_LINK_ACL_MSG, "denied",
6742+ gr_to_filename(old_dentry, old_mnt), to,
6743+ DEFAULTSECARGS);
6744+ return 0;
6745+ } else if (unlikely((mode & needmode) != needmode))
6746+ return 0;
6747+
6748+ return (GR_WRITE | GR_CREATE);
6749+}
6750+
6751+__u32
6752+gr_acl_handle_symlink(const struct dentry * new_dentry,
6753+ const struct dentry * parent_dentry,
6754+ const struct vfsmount * parent_mnt, const char *from)
6755+{
6756+ __u32 needmode = GR_WRITE | GR_CREATE;
6757+ __u32 mode;
6758+
6759+ mode =
6760+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
6761+ GR_CREATE | GR_AUDIT_CREATE |
6762+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
6763+
6764+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
6765+ security_audit(GR_SYMLINK_ACL_MSG, "successful",
6766+ from, gr_to_filename(new_dentry, parent_mnt),
6767+ DEFAULTSECARGS);
6768+ return mode;
6769+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
6770+ security_alert(GR_SYMLINK_ACL_MSG, "denied",
6771+ from, gr_to_filename(new_dentry, parent_mnt),
6772+ DEFAULTSECARGS);
6773+ return 0;
6774+ } else if (unlikely((mode & needmode) != needmode))
6775+ return 0;
6776+
6777+ return (GR_WRITE | GR_CREATE);
6778+}
6779+
6780+#define generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt, reqmode, fmt) \
6781+{ \
6782+ __u32 mode; \
6783+ \
6784+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS); \
6785+ \
6786+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) { \
6787+ security_audit(fmt, "successful", \
6788+ gr_to_filename(new_dentry, parent_mnt), \
6789+ DEFAULTSECARGS); \
6790+ return mode; \
6791+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) { \
6792+ security_alert(fmt, "denied", \
6793+ gr_to_filename(new_dentry, parent_mnt), \
6794+ DEFAULTSECARGS); \
6795+ return 0; \
6796+ } else if (unlikely((mode & (reqmode)) != (reqmode))) \
6797+ return 0; \
6798+ \
6799+ return (reqmode); \
6800+}
6801+
6802+__u32
6803+gr_acl_handle_mknod(const struct dentry * new_dentry,
6804+ const struct dentry * parent_dentry,
6805+ const struct vfsmount * parent_mnt,
6806+ const int mode)
6807+{
6808+ __u32 reqmode = GR_WRITE | GR_CREATE;
6809+ if (unlikely(mode & (S_ISUID | S_ISGID)))
6810+ reqmode |= GR_SETID;
6811+
6812+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
6813+ reqmode, GR_MKNOD_ACL_MSG);
6814+}
6815+
6816+__u32
6817+gr_acl_handle_mkdir(const struct dentry *new_dentry,
6818+ const struct dentry *parent_dentry,
6819+ const struct vfsmount *parent_mnt)
6820+{
6821+ generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
6822+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
6823+}
6824+
6825+#define RENAME_CHECK_SUCCESS(old, new) \
6826+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
6827+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
6828+
6829+int
6830+gr_acl_handle_rename(struct dentry *new_dentry,
6831+ struct dentry *parent_dentry,
6832+ const struct vfsmount *parent_mnt,
6833+ struct dentry *old_dentry,
6834+ struct inode *old_parent_inode,
6835+ struct vfsmount *old_mnt, const char *newname)
6836+{
6837+ __u8 gr_replace = 1;
6838+ __u32 comp1, comp2;
6839+ int error = 0;
6840+
6841+ if (unlikely(!gr_acl_is_enabled()))
6842+ return 1;
6843+
6844+ if (!new_dentry->d_inode) {
6845+ gr_replace = 0;
6846+
6847+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
6848+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
6849+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
6850+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
6851+ GR_DELETE | GR_AUDIT_DELETE |
6852+ GR_AUDIT_READ | GR_AUDIT_WRITE |
6853+ GR_SUPPRESS, old_mnt);
6854+ } else {
6855+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
6856+ GR_CREATE | GR_DELETE |
6857+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
6858+ GR_AUDIT_READ | GR_AUDIT_WRITE |
6859+ GR_SUPPRESS, parent_mnt);
6860+ comp2 =
6861+ gr_search_file(old_dentry,
6862+ GR_READ | GR_WRITE | GR_AUDIT_READ |
6863+ GR_DELETE | GR_AUDIT_DELETE |
6864+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
6865+ }
6866+
6867+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
6868+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
6869+ security_audit(GR_RENAME_ACL_MSG, "successful",
6870+ gr_to_filename(old_dentry, old_mnt),
6871+ newname, DEFAULTSECARGS);
6872+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
6873+ && !(comp2 & GR_SUPPRESS)) {
6874+ security_alert(GR_RENAME_ACL_MSG, "denied",
6875+ gr_to_filename(old_dentry, old_mnt), newname,
6876+ DEFAULTSECARGS);
6877+ error = -EACCES;
6878+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
6879+ error = -EACCES;
6880+
6881+ if (error)
6882+ return error;
6883+
6884+ error = gr_handle_rename(old_parent_inode, parent_dentry->d_inode,
6885+ old_dentry, new_dentry, old_mnt, gr_replace);
6886+
6887+ return error;
6888+}
6889+
6890+void
6891+gr_acl_handle_exit(void)
6892+{
6893+ u16 id;
6894+ char *rolename;
6895+
6896+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
6897+ id = current->acl_role_id;
6898+ rolename = current->role->rolename;
6899+ gr_set_acls(1);
6900+ security_alert_good(GR_SPROLEL_ACL_MSG,
6901+ rolename, id, DEFAULTSECARGS);
6902+ }
6903+
6904+ if (current->exec_file) {
6905+ fput(current->exec_file);
6906+ current->exec_file = NULL;
6907+ }
6908+}
6909+
6910+int
6911+gr_acl_handle_procpidmem(const struct task_struct *task)
6912+{
6913+ if (unlikely(!gr_acl_is_enabled()))
6914+ return 0;
6915+
6916+ if (task->acl->mode & GR_PROTPROCFD)
6917+ return -EACCES;
6918+
6919+ return 0;
6920+}
6921diff -urN linux-2.4.22/grsecurity/gracl_ip.c linux-2.4.22/grsecurity/gracl_ip.c
6922--- linux-2.4.22/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
6923+++ linux-2.4.22/grsecurity/gracl_ip.c 2003-09-02 19:29:42.000000000 -0400
6924@@ -0,0 +1,235 @@
6925+/*
6926+ * grsecurity/gracl_ip.c
6927+ * Copyright Brad Spengler 2002, 2003
6928+ *
6929+ */
6930+
6931+#include <linux/kernel.h>
6932+#include <asm/uaccess.h>
6933+#include <asm/errno.h>
6934+#include <net/sock.h>
6935+#include <linux/file.h>
6936+#include <linux/fs.h>
6937+#include <linux/net.h>
6938+#include <linux/in.h>
6939+#include <linux/skbuff.h>
6940+#include <linux/ip.h>
6941+#include <linux/udp.h>
6942+#include <linux/smp_lock.h>
6943+#include <linux/types.h>
6944+#include <linux/sched.h>
6945+#include <linux/gracl.h>
6946+#include <linux/grsecurity.h>
6947+#include <linux/grinternal.h>
6948+
6949+#define GR_BIND 0x01
6950+#define GR_CONNECT 0x02
6951+
6952+static const char * gr_protocols[256] = {
6953+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
6954+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
6955+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
6956+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
6957+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
6958+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
6959+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
6960+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
6961+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
6962+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
6963+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
6964+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
6965+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
6966+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
6967+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
6968+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
6969+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
6970+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
6971+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
6972+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
6973+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
6974+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
6975+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
6976+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
6977+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
6978+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
6979+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
6980+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
6981+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
6982+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
6983+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
6984+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
6985+ };
6986+
6987+static const char * gr_socktypes[11] = {
6988+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
6989+ "unknown:7", "unknown:8", "unknown:9", "packet"
6990+ };
6991+
6992+static __inline__ const char *
6993+gr_proto_to_name(unsigned char proto)
6994+{
6995+ return gr_protocols[proto];
6996+}
6997+
6998+static __inline__ const char *
6999+gr_socktype_to_name(unsigned char type)
7000+{
7001+ return gr_socktypes[type];
7002+}
7003+
7004+int
7005+gr_search_socket(const int domain, const int type, const int protocol)
7006+{
7007+ struct acl_subject_label *curr;
7008+
7009+ if (unlikely(!gr_acl_is_enabled()))
7010+ goto exit;
7011+
7012+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
7013+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
7014+ goto exit; // let the kernel handle it
7015+
7016+ curr = current->acl;
7017+
7018+ if (!curr->ips)
7019+ goto exit;
7020+
7021+ if ((curr->ip_type & (1 << type)) &&
7022+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
7023+ goto exit;
7024+
7025+ if (curr->mode & GR_LEARN) {
7026+ /* we don't place acls on raw sockets , and sometimes
7027+ dgram/ip sockets are opened for ioctl and not
7028+ bind/connect, so we'll fake a bind learn log */
7029+ if (type == SOCK_RAW || type == SOCK_PACKET) {
7030+ __u32 fakeip = 0;
7031+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
7032+ current->role->roletype, current->uid,
7033+ current->gid, current->exec_file ?
7034+ gr_to_filename(current->exec_file->f_dentry,
7035+ current->exec_file->f_vfsmnt) :
7036+ curr->filename, curr->filename,
7037+ NIPQUAD(fakeip), 0, type,
7038+ protocol, GR_CONNECT, NIPQUAD(current->curr_ip));
7039+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
7040+ __u32 fakeip = 0;
7041+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
7042+ current->role->roletype, current->uid,
7043+ current->gid, current->exec_file ?
7044+ gr_to_filename(current->exec_file->f_dentry,
7045+ current->exec_file->f_vfsmnt) :
7046+ curr->filename, curr->filename,
7047+ NIPQUAD(fakeip), 0, type,
7048+ protocol, GR_BIND, NIPQUAD(current->curr_ip));
7049+ }
7050+ /* we'll log when they use connect or bind */
7051+ goto exit;
7052+ }
7053+
7054+ security_alert(GR_SOCK_MSG, "inet", gr_socktype_to_name(type),
7055+ gr_proto_to_name(protocol), DEFAULTSECARGS);
7056+
7057+ return 0;
7058+ exit:
7059+ return 1;
7060+}
7061+
7062+static __inline__ int
7063+gr_search_connectbind(const int mode, const struct sock *sk,
7064+ const struct sockaddr_in *addr, const int type)
7065+{
7066+ struct acl_subject_label *curr;
7067+ struct acl_ip_label *ip;
7068+ unsigned long i;
7069+ __u32 ip_addr = 0;
7070+ __u16 ip_port = 0;
7071+
7072+ if (unlikely(!gr_acl_is_enabled() || sk->family != PF_INET))
7073+ return 1;
7074+
7075+ curr = current->acl;
7076+
7077+ if (!curr->ips)
7078+ return 1;
7079+
7080+ ip_addr = addr->sin_addr.s_addr;
7081+ ip_port = ntohs(addr->sin_port);
7082+
7083+ for (i = 0; i < curr->ip_num; i++) {
7084+ ip = *(curr->ips + i);
7085+ if ((ip->mode & mode) &&
7086+ (ip_port >= ip->low) &&
7087+ (ip_port <= ip->high) &&
7088+ ((ntohl(ip_addr) & ip->netmask) ==
7089+ (ntohl(ip->addr) & ip->netmask))
7090+ && (ip->
7091+ proto[sk->protocol / 32] & (1 << (sk->protocol % 32)))
7092+ && (ip->type & (1 << type)))
7093+ return 1;
7094+ }
7095+
7096+ if (curr->mode & GR_LEARN) {
7097+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
7098+ current->role->roletype, current->uid,
7099+ current->gid, current->exec_file ?
7100+ gr_to_filename(current->exec_file->f_dentry,
7101+ current->exec_file->f_vfsmnt) :
7102+ curr->filename, curr->filename,
7103+ NIPQUAD(ip_addr), ip_port, type,
7104+ sk->protocol, mode, NIPQUAD(current->curr_ip));
7105+ return 1;
7106+ }
7107+
7108+ if (mode == GR_BIND)
7109+ security_alert(GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port,
7110+ gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
7111+ DEFAULTSECARGS);
7112+ else if (mode == GR_CONNECT)
7113+ security_alert(GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port,
7114+ gr_socktype_to_name(type), gr_proto_to_name(sk->protocol),
7115+ DEFAULTSECARGS);
7116+
7117+ return 0;
7118+}
7119+
7120+int
7121+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
7122+{
7123+ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
7124+}
7125+
7126+int
7127+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
7128+{
7129+ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
7130+}
7131+
7132+int
7133+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
7134+{
7135+ if (addr)
7136+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
7137+ else {
7138+ struct sockaddr_in sin;
7139+
7140+ sin.sin_addr.s_addr = sk->daddr;
7141+ sin.sin_port = sk->dport;
7142+
7143+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
7144+ }
7145+}
7146+
7147+int
7148+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
7149+{
7150+ struct sockaddr_in sin;
7151+
7152+ if (unlikely(skb->len < sizeof (struct udphdr)))
7153+ return 1; // skip this packet
7154+
7155+ sin.sin_addr.s_addr = skb->nh.iph->saddr;
7156+ sin.sin_port = skb->h.uh->source;
7157+
7158+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
7159+}
7160diff -urN linux-2.4.22/grsecurity/gracl_learn.c linux-2.4.22/grsecurity/gracl_learn.c
7161--- linux-2.4.22/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
7162+++ linux-2.4.22/grsecurity/gracl_learn.c 2003-09-02 19:29:42.000000000 -0400
7163@@ -0,0 +1,228 @@
7164+#include <linux/kernel.h>
7165+#include <linux/mm.h>
7166+#include <linux/sched.h>
7167+#include <linux/poll.h>
7168+#include <linux/smp_lock.h>
7169+#include <linux/string.h>
7170+#include <linux/file.h>
7171+#include <linux/types.h>
7172+#include <linux/vmalloc.h>
7173+#include <linux/grinternal.h>
7174+
7175+extern ssize_t write_grsec_handler(struct file * file, const char * buf,
7176+ size_t count, loff_t *ppos);
7177+extern int gr_acl_is_enabled(void);
7178+
7179+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
7180+static DECLARE_WAIT_QUEUE_HEAD(input_wait);
7181+static atomic_t learn_buffer_count = ATOMIC_INIT(0);
7182+static int gr_learn_attached;
7183+
7184+#define LEARN_BUFFER_SLOTS 256
7185+#define LEARN_BUFFER_SIZE 16384
7186+
7187+static spinlock_t learn_buffer_lock[LEARN_BUFFER_SLOTS] = { [0 ... (LEARN_BUFFER_SLOTS - 1)] = SPIN_LOCK_UNLOCKED };
7188+static char *learn_buffer[LEARN_BUFFER_SLOTS];
7189+static int learn_buffer_len[LEARN_BUFFER_SLOTS];
7190+
7191+static ssize_t
7192+read_learn(struct file *file, char * buf, size_t count, loff_t * ppos)
7193+{
7194+ DECLARE_WAITQUEUE(wait, current);
7195+ ssize_t retval = 0;
7196+ char *tmp;
7197+ unsigned int len;
7198+ int i;
7199+
7200+ add_wait_queue(&learn_wait, &wait);
7201+ set_current_state(TASK_INTERRUPTIBLE);
7202+ do {
7203+ if (atomic_read(&learn_buffer_count) > 1)
7204+ break;
7205+
7206+ if (file->f_flags & O_NONBLOCK) {
7207+ retval = -EAGAIN;
7208+ goto out;
7209+ }
7210+ if (signal_pending(current)) {
7211+ retval = -ERESTARTSYS;
7212+ goto out;
7213+ }
7214+
7215+ schedule();
7216+ } while (1);
7217+
7218+
7219+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
7220+ spin_lock(&learn_buffer_lock[i]);
7221+ len = learn_buffer_len[i];
7222+ tmp = learn_buffer[i];
7223+ if (!len || !tmp) {
7224+ spin_unlock(&learn_buffer_lock[i]);
7225+ continue;
7226+ }
7227+ learn_buffer[i] = NULL;
7228+ learn_buffer_len[i] = 0;
7229+ spin_unlock(&learn_buffer_lock[i]);
7230+
7231+ if (count < ((i * LEARN_BUFFER_SIZE) + len)) {
7232+ retval = -EINVAL;
7233+ vfree(tmp);
7234+ goto out;
7235+ }
7236+ if (copy_to_user(buf + (i * LEARN_BUFFER_SIZE), tmp, len)) {
7237+ retval = -EFAULT;
7238+ vfree(tmp);
7239+ goto out;
7240+ }
7241+
7242+ retval += len;
7243+ vfree(tmp);
7244+ atomic_dec(&learn_buffer_count);
7245+ atomic_dec(&learn_buffer_count);
7246+ }
7247+
7248+ wake_up(&input_wait);
7249+out:
7250+ set_current_state(TASK_RUNNING);
7251+ remove_wait_queue(&learn_wait, &wait);
7252+ return retval;
7253+}
7254+
7255+static unsigned int
7256+poll_learn(struct file * file, poll_table * wait)
7257+{
7258+ poll_wait(file, &learn_wait, wait);
7259+
7260+ if (atomic_read(&learn_buffer_count) > 1)
7261+ return (POLLIN | POLLRDNORM);
7262+
7263+ return 0;
7264+}
7265+
7266+void
7267+gr_clear_learn_entries(void)
7268+{
7269+ int i;
7270+
7271+ atomic_set(&learn_buffer_count, 0);
7272+ wake_up(&input_wait);
7273+
7274+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
7275+ if (learn_buffer_len[i]) {
7276+ vfree(learn_buffer[i]);
7277+ learn_buffer[i] = NULL;
7278+ learn_buffer_len[i] = 0;
7279+ }
7280+ }
7281+
7282+ return;
7283+}
7284+
7285+void
7286+gr_add_learn_entry(const char *fmt, ...)
7287+{
7288+ DECLARE_WAITQUEUE(wait, current);
7289+ va_list args;
7290+ char *tmpbuf;
7291+ char *buf;
7292+ int i;
7293+ unsigned int len;
7294+
7295+ if (!gr_learn_attached)
7296+ return;
7297+
7298+ tmpbuf = vmalloc(LEARN_BUFFER_SIZE);
7299+
7300+ if (tmpbuf == NULL)
7301+ return;
7302+
7303+ va_start(args, fmt);
7304+ len = vsnprintf(tmpbuf, LEARN_BUFFER_SIZE, fmt, args);
7305+ va_end(args);
7306+
7307+ if (len < 0)
7308+ len = LEARN_BUFFER_SIZE - 1;
7309+
7310+ buf = vmalloc(len + 1);
7311+
7312+ if (buf == NULL) {
7313+ vfree(tmpbuf);
7314+ return;
7315+ }
7316+
7317+ memcpy(buf, tmpbuf, len);
7318+ buf[len] = '\0';
7319+ vfree(tmpbuf);
7320+
7321+ add_wait_queue(&input_wait, &wait);
7322+
7323+ atomic_inc(&learn_buffer_count);
7324+ if (atomic_read(&learn_buffer_count) > ((2 * (LEARN_BUFFER_SLOTS - 1)) + 1)) {
7325+ /* don't sleep under the BKL */
7326+// if (unlikely(current->lock_depth >= 0)) {
7327+ remove_wait_queue(&input_wait, &wait);
7328+ atomic_dec(&learn_buffer_count);
7329+ vfree(buf);
7330+ return;
7331+// }
7332+// sleep_on(&input_wait);
7333+ }
7334+
7335+ if (!gr_acl_is_enabled()) {
7336+ remove_wait_queue(&input_wait, &wait);
7337+ atomic_dec(&learn_buffer_count);
7338+ vfree(buf);
7339+ return;
7340+ }
7341+
7342+ for (i = 0; i < LEARN_BUFFER_SLOTS; i++) {
7343+ spin_lock(&learn_buffer_lock[i]);
7344+
7345+ if (learn_buffer_len[i]) {
7346+ spin_unlock(&learn_buffer_lock[i]);
7347+ continue;
7348+ }
7349+
7350+ learn_buffer[i] = buf;
7351+
7352+ learn_buffer_len[i] = len + 1;
7353+
7354+ atomic_inc(&learn_buffer_count);
7355+ spin_unlock(&learn_buffer_lock[i]);
7356+ break;
7357+ }
7358+
7359+ remove_wait_queue(&input_wait, &wait);
7360+ wake_up_interruptible(&learn_wait);
7361+
7362+ return;
7363+}
7364+
7365+static int
7366+open_learn(struct inode *inode, struct file *file)
7367+{
7368+ if (file->f_mode & FMODE_READ && gr_learn_attached)
7369+ return -EBUSY;
7370+ else if (file->f_mode & FMODE_READ)
7371+ gr_learn_attached = 1;
7372+
7373+ return 0;
7374+}
7375+
7376+static int
7377+close_learn(struct inode *inode, struct file *file)
7378+{
7379+ if (file->f_mode & FMODE_READ)
7380+ gr_learn_attached = 0;
7381+
7382+ return 0;
7383+}
7384+
7385+struct file_operations grsec_fops = {
7386+ read: read_learn,
7387+ write: write_grsec_handler,
7388+ open: open_learn,
7389+ release: close_learn,
7390+ poll: poll_learn,
7391+};
7392diff -urN linux-2.4.22/grsecurity/gracl_res.c linux-2.4.22/grsecurity/gracl_res.c
7393--- linux-2.4.22/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
7394+++ linux-2.4.22/grsecurity/gracl_res.c 2003-09-02 19:29:42.000000000 -0400
7395@@ -0,0 +1,45 @@
7396+/* resource handling routines (c) Brad Spengler 2002, 2003 */
7397+
7398+#include <linux/kernel.h>
7399+#include <linux/sched.h>
7400+#include <linux/gracl.h>
7401+#include <linux/grinternal.h>
7402+
7403+static const char *restab_log[11] = {
7404+ "RLIMIT_CPU",
7405+ "RLIMIT_FSIZE",
7406+ "RLIMIT_DATA",
7407+ "RLIMIT_STACK",
7408+ "RLIMIT_CORE",
7409+ "RLIMIT_RSS",
7410+ "RLIMIT_NPROC",
7411+ "RLIMIT_NOFILE",
7412+ "RLIMIT_MEMLOCK",
7413+ "RLIMIT_AS",
7414+ "RLIMIT_LOCKS"
7415+};
7416+
7417+__inline__ void
7418+gr_log_resource(const struct task_struct *task,
7419+ const int res, const unsigned long wanted)
7420+{
7421+ if (unlikely(res == RLIMIT_NPROC &&
7422+ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
7423+ cap_raised(task->cap_effective, CAP_SYS_RESOURCE))))
7424+ return;
7425+
7426+ if (unlikely(wanted >= task->rlim[res].rlim_cur &&
7427+ task->rlim[res].rlim_cur != RLIM_INFINITY))
7428+ security_alert(GR_RESOURCE_MSG, wanted, restab_log[res],
7429+ task->rlim[res].rlim_cur,
7430+ gr_task_fullpath(task), task->comm,
7431+ task->pid, task->uid, task->euid,
7432+ task->gid, task->egid,
7433+ gr_parent_task_fullpath(task),
7434+ task->p_pptr->comm,
7435+ task->p_pptr->pid, task->p_pptr->uid,
7436+ task->p_pptr->euid, task->p_pptr->gid,
7437+ task->p_pptr->egid);
7438+
7439+ return;
7440+}
7441diff -urN linux-2.4.22/grsecurity/gracl_segv.c linux-2.4.22/grsecurity/gracl_segv.c
7442--- linux-2.4.22/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
7443+++ linux-2.4.22/grsecurity/gracl_segv.c 2003-09-02 19:29:42.000000000 -0400
7444@@ -0,0 +1,327 @@
7445+/*
7446+ * grsecurity/gracl_segv.c
7447+ * Copyright Brad Spengler 2002, 2003
7448+ *
7449+ */
7450+
7451+#include <linux/kernel.h>
7452+#include <linux/mm.h>
7453+#include <asm/uaccess.h>
7454+#include <asm/errno.h>
7455+#include <asm/mman.h>
7456+#include <net/sock.h>
7457+#include <linux/file.h>
7458+#include <linux/fs.h>
7459+#include <linux/net.h>
7460+#include <linux/in.h>
7461+#include <linux/smp_lock.h>
7462+#include <linux/slab.h>
7463+#include <linux/types.h>
7464+#include <linux/sched.h>
7465+#include <linux/timer.h>
7466+#include <linux/gracl.h>
7467+#include <linux/grsecurity.h>
7468+#include <linux/grinternal.h>
7469+
7470+static struct crash_uid *uid_set;
7471+static unsigned short uid_used;
7472+static rwlock_t gr_uid_lock = RW_LOCK_UNLOCKED;
7473+extern rwlock_t gr_inode_lock;
7474+extern __inline__ struct acl_subject_label *lookup_acl_subj_label(const ino_t
7475+ inode,
7476+ const kdev_t
7477+ dev,
7478+ struct
7479+ acl_role_label
7480+ *role);
7481+
7482+int
7483+gr_init_uidset(void)
7484+{
7485+ uid_set =
7486+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
7487+ uid_used = 0;
7488+
7489+ return uid_set ? 1 : 0;
7490+}
7491+
7492+void
7493+gr_free_uidset(void)
7494+{
7495+ if (uid_set)
7496+ kfree(uid_set);
7497+
7498+ return;
7499+}
7500+
7501+int
7502+gr_find_uid(const uid_t uid)
7503+{
7504+ struct crash_uid *tmp = uid_set;
7505+ uid_t buid;
7506+ int low = 0, high = uid_used - 1, mid;
7507+
7508+ while (high >= low) {
7509+ mid = (low + high) >> 1;
7510+ buid = tmp[mid].uid;
7511+ if (buid == uid)
7512+ return mid;
7513+ if (buid > uid)
7514+ high = mid - 1;
7515+ if (buid < uid)
7516+ low = mid + 1;
7517+ }
7518+
7519+ return -1;
7520+}
7521+
7522+static __inline__ void
7523+gr_insertsort(void)
7524+{
7525+ unsigned short i, j;
7526+ struct crash_uid index;
7527+
7528+ for (i = 1; i < uid_used; i++) {
7529+ index = uid_set[i];
7530+ j = i;
7531+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
7532+ uid_set[j] = uid_set[j - 1];
7533+ j--;
7534+ }
7535+ uid_set[j] = index;
7536+ }
7537+
7538+ return;
7539+}
7540+
7541+static __inline__ void
7542+gr_insert_uid(const uid_t uid, const unsigned long expires)
7543+{
7544+ int loc;
7545+
7546+ if (uid_used == GR_UIDTABLE_MAX)
7547+ return;
7548+
7549+ loc = gr_find_uid(uid);
7550+
7551+ if (loc >= 0) {
7552+ uid_set[loc].expires = expires;
7553+ return;
7554+ }
7555+
7556+ uid_set[uid_used].uid = uid;
7557+ uid_set[uid_used].expires = expires;
7558+ uid_used++;
7559+
7560+ gr_insertsort();
7561+
7562+ return;
7563+}
7564+
7565+void
7566+gr_remove_uid(const unsigned short loc)
7567+{
7568+ unsigned short i;
7569+
7570+ for (i = loc + 1; i < uid_used; i++)
7571+ uid_set[i - i] = uid_set[i];
7572+
7573+ uid_used--;
7574+
7575+ return;
7576+}
7577+
7578+int
7579+gr_check_crash_uid(const uid_t uid)
7580+{
7581+ int loc;
7582+
7583+ if (unlikely(!gr_acl_is_enabled()))
7584+ return 0;
7585+
7586+ read_lock(&gr_uid_lock);
7587+ loc = gr_find_uid(uid);
7588+ read_unlock(&gr_uid_lock);
7589+
7590+ if (loc < 0)
7591+ return 0;
7592+
7593+ write_lock(&gr_uid_lock);
7594+ if (time_before_eq(uid_set[loc].expires, jiffies))
7595+ gr_remove_uid(loc);
7596+ else {
7597+ write_unlock(&gr_uid_lock);
7598+ return 1;
7599+ }
7600+
7601+ write_unlock(&gr_uid_lock);
7602+ return 0;
7603+}
7604+
7605+static __inline__ int
7606+proc_is_setxid(const struct task_struct *task)
7607+{
7608+ if (task->uid != task->euid || task->uid != task->suid ||
7609+ task->uid != task->fsuid)
7610+ return 1;
7611+ if (task->gid != task->egid || task->gid != task->sgid ||
7612+ task->gid != task->fsgid)
7613+ return 1;
7614+
7615+ return 0;
7616+}
7617+static __inline__ int
7618+gr_fake_force_sig(int sig, struct task_struct *t)
7619+{
7620+ unsigned long int flags;
7621+
7622+ spin_lock_irqsave(&t->sigmask_lock, flags);
7623+ if (t->sig == NULL) {
7624+ spin_unlock_irqrestore(&t->sigmask_lock, flags);
7625+ return -ESRCH;
7626+ }
7627+
7628+ if (t->sig->action[sig - 1].sa.sa_handler == SIG_IGN)
7629+ t->sig->action[sig - 1].sa.sa_handler = SIG_DFL;
7630+ sigdelset(&t->blocked, sig);
7631+ recalc_sigpending(t);
7632+ spin_unlock_irqrestore(&t->sigmask_lock, flags);
7633+
7634+ return send_sig_info(sig, (void *) 1L, t);
7635+}
7636+
7637+void
7638+gr_handle_crash(struct task_struct *task, const int sig)
7639+{
7640+ struct acl_subject_label *curr;
7641+ struct acl_subject_label *curr2;
7642+ struct task_struct *tsk;
7643+
7644+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
7645+ return;
7646+
7647+ if (unlikely(!gr_acl_is_enabled()))
7648+ return;
7649+
7650+ curr = task->acl;
7651+
7652+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
7653+ return;
7654+
7655+ if (time_before_eq(curr->expires, jiffies)) {
7656+ curr->expires = 0;
7657+ curr->crashes = 0;
7658+ }
7659+
7660+ curr->crashes++;
7661+
7662+ if (!curr->expires)
7663+ curr->expires = jiffies + curr->res[GR_CRASH_RES].rlim_max;
7664+
7665+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
7666+ time_after(curr->expires, jiffies)) {
7667+ if (task->uid && proc_is_setxid(task)) {
7668+ security_alert(GR_SEGVSTART_ACL_MSG,
7669+ gr_task_fullpath(task), task->comm,
7670+ task->pid, task->uid, task->euid,
7671+ task->gid, task->egid,
7672+ gr_parent_task_fullpath(task),
7673+ task->p_pptr->comm, task->p_pptr->pid,
7674+ task->p_pptr->uid, task->p_pptr->euid,
7675+ task->p_pptr->gid, task->p_pptr->egid,
7676+ task->uid,
7677+ curr->res[GR_CRASH_RES].rlim_max / HZ);
7678+ write_lock(&gr_uid_lock);
7679+ gr_insert_uid(task->uid, curr->expires);
7680+ write_unlock(&gr_uid_lock);
7681+ curr->expires = 0;
7682+ curr->crashes = 0;
7683+ read_lock(&tasklist_lock);
7684+ for_each_task(tsk) {
7685+ if (tsk != task && tsk->uid == task->uid)
7686+ gr_fake_force_sig(SIGKILL, tsk);
7687+ }
7688+ read_unlock(&tasklist_lock);
7689+ } else {
7690+ security_alert(GR_SEGVNOSUID_ACL_MSG,
7691+ gr_task_fullpath(task), task->comm,
7692+ task->pid, task->uid, task->euid,
7693+ task->gid, task->egid,
7694+ gr_parent_task_fullpath(task),
7695+ task->p_pptr->comm, task->p_pptr->pid,
7696+ task->p_pptr->uid, task->p_pptr->euid,
7697+ task->p_pptr->gid, task->p_pptr->egid,
7698+ kdevname(curr->device), curr->inode,
7699+ curr->res[GR_CRASH_RES].rlim_max / HZ);
7700+ read_lock(&tasklist_lock);
7701+ for_each_task(tsk) {
7702+ if (likely(tsk != task)) {
7703+ curr2 = tsk->acl;
7704+
7705+ if (curr2->device == curr->device &&
7706+ curr2->inode == curr->inode)
7707+ gr_fake_force_sig(SIGKILL, tsk);
7708+ }
7709+ }
7710+ read_unlock(&tasklist_lock);
7711+ }
7712+ }
7713+
7714+ return;
7715+}
7716+
7717+int
7718+gr_check_crash_exec(const struct file *filp)
7719+{
7720+ struct acl_subject_label *curr;
7721+
7722+ if (unlikely(!gr_acl_is_enabled()))
7723+ return 0;
7724+
7725+ read_lock(&gr_inode_lock);
7726+ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
7727+ filp->f_dentry->d_inode->i_dev,
7728+ current->role);
7729+ read_unlock(&gr_inode_lock);
7730+
7731+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
7732+ (!curr->crashes && !curr->expires))
7733+ return 0;
7734+
7735+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
7736+ time_after(curr->expires, jiffies))
7737+ return 1;
7738+ else if (time_before_eq(curr->expires, jiffies)) {
7739+ curr->crashes = 0;
7740+ curr->expires = 0;
7741+ }
7742+
7743+ return 0;
7744+}
7745+
7746+void
7747+gr_handle_alertkill(void)
7748+{
7749+ struct acl_subject_label *curracl;
7750+ __u32 curr_ip;
7751+ struct task_struct *task;
7752+
7753+ if (unlikely(!gr_acl_is_enabled()))
7754+ return;
7755+
7756+ curracl = current->acl;
7757+ curr_ip = current->curr_ip;
7758+
7759+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip &&
7760+ (curr_ip != 0xffffffff)) {
7761+ read_lock(&tasklist_lock);
7762+ for_each_task(task) {
7763+ if (task->curr_ip == curr_ip)
7764+ gr_fake_force_sig(SIGKILL, task);
7765+ }
7766+ read_unlock(&tasklist_lock);
7767+ } else if (curracl->mode & GR_KILLPROC)
7768+ gr_fake_force_sig(SIGKILL, current);
7769+
7770+ return;
7771+}
7772diff -urN linux-2.4.22/grsecurity/gracl_shm.c linux-2.4.22/grsecurity/gracl_shm.c
7773--- linux-2.4.22/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
7774+++ linux-2.4.22/grsecurity/gracl_shm.c 2003-09-02 19:29:42.000000000 -0400
7775@@ -0,0 +1,36 @@
7776+/* shared memory handling routines, (c) Brad Spengler 2002, 2003 */
7777+
7778+#include <linux/kernel.h>
7779+#include <linux/mm.h>
7780+#include <linux/sched.h>
7781+#include <linux/file.h>
7782+#include <linux/ipc.h>
7783+#include <linux/gracl.h>
7784+#include <linux/grsecurity.h>
7785+#include <linux/grinternal.h>
7786+
7787+int
7788+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
7789+ const time_t shm_createtime, const uid_t cuid, const int shmid)
7790+{
7791+ struct task_struct *task;
7792+
7793+ if (!gr_acl_is_enabled())
7794+ return 1;
7795+
7796+ task = find_task_by_pid(shm_cprid);
7797+
7798+ if (unlikely(!task))
7799+ task = find_task_by_pid(shm_lapid);
7800+
7801+ if (unlikely(task && ((task->start_time < shm_createtime) ||
7802+ (task->pid == shm_lapid)) &&
7803+ (task->acl->mode & GR_PROTSHM) &&
7804+ (task->acl != current->acl))) {
7805+ security_alert(GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid,
7806+ DEFAULTSECARGS);
7807+ return 0;
7808+ }
7809+
7810+ return 1;
7811+}
7812diff -urN linux-2.4.22/grsecurity/grsec_chdir.c linux-2.4.22/grsecurity/grsec_chdir.c
7813--- linux-2.4.22/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
7814+++ linux-2.4.22/grsecurity/grsec_chdir.c 2003-09-02 19:29:42.000000000 -0400
7815@@ -0,0 +1,20 @@
7816+#include <linux/kernel.h>
7817+#include <linux/sched.h>
7818+#include <linux/fs.h>
7819+#include <linux/file.h>
7820+#include <linux/grsecurity.h>
7821+#include <linux/grinternal.h>
7822+
7823+void
7824+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
7825+{
7826+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
7827+ if ((grsec_enable_chdir && grsec_enable_group &&
7828+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
7829+ !grsec_enable_group)) {
7830+ security_audit(GR_CHDIR_AUDIT_MSG, gr_to_filename(dentry, mnt),
7831+ DEFAULTSECARGS);
7832+ }
7833+#endif
7834+ return;
7835+}
7836diff -urN linux-2.4.22/grsecurity/grsec_chroot.c linux-2.4.22/grsecurity/grsec_chroot.c
7837--- linux-2.4.22/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
7838+++ linux-2.4.22/grsecurity/grsec_chroot.c 2003-09-02 19:29:42.000000000 -0400
7839@@ -0,0 +1,333 @@
7840+#include <linux/kernel.h>
7841+#include <linux/sched.h>
7842+#include <linux/file.h>
7843+#include <linux/fs.h>
7844+#include <linux/types.h>
7845+#include <linux/grinternal.h>
7846+
7847+int
7848+gr_handle_chroot_unix(const pid_t pid)
7849+{
7850+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
7851+ struct task_struct *p, **htable;
7852+
7853+ if (unlikely(!grsec_enable_chroot_unix))
7854+ return 1;
7855+
7856+ if (likely(!proc_is_chrooted(current)))
7857+ return 1;
7858+
7859+ read_lock(&tasklist_lock);
7860+
7861+ htable = &pidhash[pid_hashfn(pid)];
7862+
7863+ for (p = *htable; p && p->pid != pid; p = p->pidhash_next) ;
7864+
7865+ if (unlikely(p && !have_same_root(current, p))) {
7866+ read_unlock(&tasklist_lock);
7867+ security_alert(GR_UNIX_CHROOT_MSG, DEFAULTSECARGS);
7868+ return 0;
7869+ }
7870+ read_unlock(&tasklist_lock);
7871+#endif
7872+ return 1;
7873+}
7874+
7875+int
7876+gr_handle_chroot_nice(void)
7877+{
7878+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
7879+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
7880+ security_alert(GR_NICE_CHROOT_MSG, DEFAULTSECARGS);
7881+ return -EPERM;
7882+ }
7883+#endif
7884+ return 0;
7885+}
7886+
7887+int
7888+gr_handle_chroot_setpriority(const struct task_struct *p, const int niceval)
7889+{
7890+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
7891+ if (grsec_enable_chroot_nice && (!have_same_root(p, current)
7892+ || (have_same_root(p, current)
15e55260 7893+ && (niceval < task_nice(p))
ada7ca3f
JR
7894+ && proc_is_chrooted(current)))) {
7895+ security_alert(GR_PRIORITY_CHROOT_MSG, p->comm, p->pid,
7896+ DEFAULTSECARGS);
7897+ return -ESRCH;
7898+ }
7899+#endif
7900+ return 0;
7901+}
7902+
7903+int
7904+gr_handle_chroot_capset(const struct task_struct *target)
7905+{
7906+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7907+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
7908+ !have_same_root(current, target)) {
7909+ security_alert(GR_CAPSET_CHROOT_MSG, target->comm, target->pid,
7910+ DEFAULTSECARGS);
7911+ return 1;
7912+ }
7913+#endif
7914+ return 0;
7915+}
7916+
7917+int
7918+gr_handle_chroot_rawio(const struct inode *inode)
7919+{
7920+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
7921+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
7922+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
7923+ return 1;
7924+#endif
7925+ return 0;
7926+}
7927+
7928+int
7929+gr_pid_is_chrooted(const struct task_struct *p)
7930+{
7931+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
7932+ if (!grsec_enable_chroot_findtask || (current->pid <= 1))
7933+ return 0;
7934+
7935+ if (p && p->fs && p->fs->root && p->fs->root->d_inode &&
7936+ child_reaper && child_reaper->fs && child_reaper->fs->root &&
7937+ child_reaper->fs->root->d_inode && current && current->fs &&
7938+ current->fs->root && current->fs->root->d_inode) {
7939+ if (proc_is_chrooted(current) && !have_same_root(current, p))
7940+ return 1;
7941+ }
7942+#endif
7943+ return 0;
7944+}
7945+
7946+int
7947+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
7948+{
7949+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
7950+ if (!grsec_enable_chroot_fchdir)
7951+ return 1;
7952+
7953+ if (!proc_is_chrooted(current))
7954+ return 1;
7955+ else {
7956+ struct dentry *dentry = u_dentry;
7957+ struct vfsmount *mnt = u_mnt;
7958+ struct dentry *realroot;
7959+ struct vfsmount *realrootmnt;
7960+ struct dentry *currentroot;
7961+ struct vfsmount *currentmnt;
7962+
7963+ read_lock(&child_reaper->fs->lock);
7964+ realrootmnt = mntget(child_reaper->fs->rootmnt);
7965+ realroot = dget(child_reaper->fs->root);
7966+ read_unlock(&child_reaper->fs->lock);
7967+
7968+ read_lock(&current->fs->lock);
7969+ currentmnt = mntget(current->fs->rootmnt);
7970+ currentroot = dget(current->fs->root);
7971+ read_unlock(&current->fs->lock);
7972+
7973+ spin_lock(&dcache_lock);
7974+ for (;;) {
7975+ if (unlikely
7976+ ((dentry == realroot && mnt == realrootmnt)
7977+ || (dentry == currentroot && mnt == currentmnt)))
7978+ break;
7979+ if (unlikely
7980+ (dentry == mnt->mnt_root || IS_ROOT(dentry))) {
7981+ if (mnt->mnt_parent == mnt)
7982+ break;
7983+ dentry = mnt->mnt_mountpoint;
7984+ mnt = mnt->mnt_parent;
7985+ continue;
7986+ }
7987+ dentry = dentry->d_parent;
7988+ }
7989+ spin_unlock(&dcache_lock);
7990+
7991+ dput(currentroot);
7992+ mntput(currentmnt);
7993+
7994+ if (dentry == realroot && mnt == realrootmnt) {
7995+ /* ok, they're definitely trying to fchdir outside of the
7996+ chroot. */
7997+ dput(realroot);
7998+ mntput(realrootmnt);
7999+ security_alert(GR_CHROOT_FCHDIR_MSG,
8000+ gr_to_filename(u_dentry, u_mnt),
8001+ DEFAULTSECARGS);
8002+ return 0;
8003+ } else {
8004+ dput(realroot);
8005+ mntput(realrootmnt);
8006+ return 1;
8007+ }
8008+ }
8009+#endif
8010+ return 1;
8011+}
8012+
8013+int
8014+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
8015+ const time_t shm_createtime)
8016+{
8017+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
8018+ struct task_struct *p, **htable;
8019+
8020+ if (unlikely(!grsec_enable_chroot_shmat))
8021+ return 1;
8022+
8023+ if (likely(!proc_is_chrooted(current)))
8024+ return 1;
8025+
8026+ read_lock(&tasklist_lock);
8027+
8028+ htable = &pidhash[pid_hashfn(shm_cprid)];
8029+
8030+ for (p = *htable; p && p->pid != shm_cprid; p = p->pidhash_next) ;
8031+
8032+ if (unlikely(p && !have_same_root(current, p) &&
8033+ (p->start_time < shm_createtime))) {
8034+ read_unlock(&tasklist_lock);
8035+ security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
8036+ return 0;
8037+ }
8038+
8039+ if (unlikely(!p)) {
8040+ htable = &pidhash[pid_hashfn(shm_lapid)];
8041+ for (p = *htable; p && p->pid != shm_lapid;
8042+ p = p->pidhash_next) ;
8043+
8044+ if (unlikely(p && !have_same_root(current, p))) {
8045+ read_unlock(&tasklist_lock);
8046+ security_alert(GR_SHMAT_CHROOT_MSG, DEFAULTSECARGS);
8047+ return 0;
8048+ }
8049+ }
8050+
8051+ read_unlock(&tasklist_lock);
8052+#endif
8053+ return 1;
8054+}
8055+
8056+void
8057+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
8058+{
8059+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
8060+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
8061+ security_audit(GR_EXEC_CHROOT_MSG, gr_to_filename(dentry, mnt),
8062+ DEFAULTSECARGS);
8063+#endif
8064+ return;
8065+}
8066+
8067+int
8068+gr_handle_chroot_mknod(const struct dentry *dentry,
8069+ const struct vfsmount *mnt, const int mode)
8070+{
8071+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
8072+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) &&
8073+ proc_is_chrooted(current)) {
8074+ security_alert(GR_MKNOD_CHROOT_MSG,
8075+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
8076+ return -EPERM;
8077+ }
8078+#endif
8079+ return 0;
8080+}
8081+
8082+int
8083+gr_handle_chroot_mount(const struct dentry *dentry,
8084+ const struct vfsmount *mnt, const char *dev_name)
8085+{
8086+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
8087+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
8088+ security_alert(GR_MOUNT_CHROOT_MSG, dev_name,
8089+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
8090+ return -EPERM;
8091+ }
8092+#endif
8093+ return 0;
8094+}
8095+
8096+int
8097+gr_handle_chroot_pivot(void)
8098+{
8099+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
8100+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
8101+ security_alert(GR_PIVOT_CHROOT_MSG, DEFAULTSECARGS);
8102+ return -EPERM;
8103+ }
8104+#endif
8105+ return 0;
8106+}
8107+
8108+int
8109+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
8110+{
8111+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
8112+ if (grsec_enable_chroot_double && proc_is_chrooted(current)) {
8113+ security_alert(GR_CHROOT_CHROOT_MSG,
8114+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
8115+ return -EPERM;
8116+ }
8117+#endif
8118+ return 0;
8119+}
8120+
8121+void
8122+gr_handle_chroot_caps(struct task_struct *task)
8123+{
8124+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
8125+ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
8126+ task->cap_permitted =
8127+ cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
8128+ task->cap_inheritable =
8129+ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
8130+ task->cap_effective =
8131+ cap_drop(task->cap_effective, GR_CHROOT_CAPS);
8132+ }
8133+#endif
8134+ return;
8135+}
8136+
8137+int
8138+gr_handle_chroot_sysctl(const int op)
8139+{
8140+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
8141+ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
8142+ && (op & 002))
8143+ return -EACCES;
8144+#endif
8145+ return 0;
8146+}
8147+
8148+void
8149+gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
8150+{
8151+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
8152+ if (grsec_enable_chroot_chdir)
8153+ set_fs_pwd(current->fs, mnt, dentry);
8154+#endif
8155+ return;
8156+}
8157+
8158+int
8159+gr_handle_chroot_chmod(const struct dentry *dentry,
8160+ const struct vfsmount *mnt, const int mode)
8161+{
8162+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
8163+ if (grsec_enable_chroot_chmod &&
8164+ ((mode & S_ISUID) || (mode & S_ISGID)) &&
8165+ proc_is_chrooted(current)) {
8166+ security_alert(GR_CHMOD_CHROOT_MSG,
8167+ gr_to_filename(dentry, mnt), DEFAULTSECARGS);
8168+ return -EPERM;
8169+ }
8170+#endif
8171+ return 0;
8172+}
8173diff -urN linux-2.4.22/grsecurity/grsec_disabled.c linux-2.4.22/grsecurity/grsec_disabled.c
8174--- linux-2.4.22/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
8175+++ linux-2.4.22/grsecurity/grsec_disabled.c 2003-09-02 19:29:42.000000000 -0400
8176@@ -0,0 +1,374 @@
8177+/*
8178+ * when grsecurity is disabled, compile all external functions into nothing
8179+ */
8180+
8181+#include <linux/kernel.h>
8182+#include <linux/config.h>
8183+#include <linux/sched.h>
8184+#include <linux/file.h>
8185+#include <linux/fs.h>
8186+#include <linux/kdev_t.h>
8187+#include <linux/net.h>
8188+#include <linux/in.h>
8189+#include <linux/ip.h>
8190+#include <linux/skbuff.h>
8191+#include <linux/sysctl.h>
8192+
8193+#ifdef CONFIG_SYSCTL
8194+__u32
8195+gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
8196+{
8197+ return mode;
8198+}
8199+#endif
8200+
8201+int
8202+gr_acl_is_enabled(void)
8203+{
8204+ return 0;
8205+}
8206+
8207+int
8208+gr_handle_rawio(const struct inode *inode)
8209+{
8210+ return 0;
8211+}
8212+
8213+void
8214+gr_acl_handle_psacct(struct task_struct *task, const long code)
8215+{
8216+ return;
8217+}
8218+
8219+int
8220+gr_handle_ptrace_exec(const struct dentry *dentry, const struct vfsmount *mnt)
8221+{
8222+ return 0;
8223+}
8224+
8225+int
8226+gr_handle_mmap(const struct file *filp, const unsigned long prot)
8227+{
8228+ return 0;
8229+}
8230+
8231+int
8232+gr_handle_ptrace(struct task_struct *task, const long request)
8233+{
8234+ return 0;
8235+}
8236+
8237+void
8238+gr_learn_resource(const struct task_struct *task,
8239+ const int res, const unsigned long wanted)
8240+{
8241+ return;
8242+}
8243+
8244+int
8245+gr_set_acls(const int type)
8246+{
8247+ return 0;
8248+}
8249+
8250+int
8251+gr_check_hidden_task(const struct task_struct *tsk)
8252+{
8253+ return 0;
8254+}
8255+
8256+int
8257+gr_check_protected_task(const struct task_struct *task)
8258+{
8259+ return 0;
8260+}
8261+
8262+__inline__ void
8263+gr_copy_label(struct task_struct *tsk)
8264+{
8265+ return;
8266+}
8267+
8268+void
8269+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
8270+{
8271+ return;
8272+}
8273+
8274+void
8275+gr_handle_delete(const ino_t ino, const kdev_t dev)
8276+{
8277+ return;
8278+}
8279+
8280+void
8281+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
8282+{
8283+ return;
8284+}
8285+
8286+void
8287+gr_handle_crash(struct task_struct *task, const int sig)
8288+{
8289+ return;
8290+}
8291+
8292+int
8293+gr_check_crash_exec(const struct file *filp)
8294+{
8295+ return 0;
8296+}
8297+
8298+int
8299+gr_check_crash_uid(const uid_t uid)
8300+{
8301+ return 0;
8302+}
8303+
8304+int
8305+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
8306+ struct dentry *old_dentry,
8307+ struct dentry *new_dentry,
8308+ struct vfsmount *mnt, const __u8 replace)
8309+{
8310+ return 0;
8311+}
8312+
8313+int
8314+gr_search_socket(const int family, const int type, const int protocol)
8315+{
8316+ return 1;
8317+}
8318+
8319+int
8320+gr_search_connectbind(const int mode, const struct socket *sock,
8321+ const struct sockaddr_in *addr)
8322+{
8323+ return 1;
8324+}
8325+
8326+int
8327+gr_is_capable(const int cap)
8328+{
8329+ return 1;
8330+}
8331+
8332+void
8333+gr_handle_alertkill(void)
8334+{
8335+ return;
8336+}
8337+
8338+__u32
8339+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
8340+{
8341+ return 1;
8342+}
8343+
8344+__u32
8345+gr_acl_handle_hidden_file(const struct dentry * dentry,
8346+ const struct vfsmount * mnt)
8347+{
8348+ return 1;
8349+}
8350+
8351+__u32
8352+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
8353+ const int fmode)
8354+{
8355+ return 1;
8356+}
8357+
8358+__u32
8359+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
8360+{
8361+ return 1;
8362+}
8363+
8364+__u32
8365+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
8366+{
8367+ return 1;
8368+}
8369+
8370+int
8371+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
8372+ unsigned int *vm_flags)
8373+{
8374+ return 1;
8375+}
8376+
8377+__u32
8378+gr_acl_handle_truncate(const struct dentry * dentry,
8379+ const struct vfsmount * mnt)
8380+{
8381+ return 1;
8382+}
8383+
8384+__u32
8385+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
8386+{
8387+ return 1;
8388+}
8389+
8390+__u32
8391+gr_acl_handle_access(const struct dentry * dentry,
8392+ const struct vfsmount * mnt, const int fmode)
8393+{
8394+ return 1;
8395+}
8396+
8397+__u32
8398+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
8399+ mode_t mode)
8400+{
8401+ return 1;
8402+}
8403+
8404+__u32
8405+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
8406+ mode_t mode)
8407+{
8408+ return 1;
8409+}
8410+
8411+__u32
8412+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
8413+{
8414+ return 1;
8415+}
8416+
8417+void
8418+grsecurity_init(void)
8419+{
8420+ return;
8421+}
8422+
8423+__u32
8424+gr_acl_handle_mknod(const struct dentry * new_dentry,
8425+ const struct dentry * parent_dentry,
8426+ const struct vfsmount * parent_mnt,
8427+ const int mode)
8428+{
8429+ return 1;
8430+}
8431+
8432+__u32
8433+gr_acl_handle_mkdir(const struct dentry * new_dentry,
8434+ const struct dentry * parent_dentry,
8435+ const struct vfsmount * parent_mnt)
8436+{
8437+ return 1;
8438+}
8439+
8440+__u32
8441+gr_acl_handle_symlink(const struct dentry * new_dentry,
8442+ const struct dentry * parent_dentry,
8443+ const struct vfsmount * parent_mnt, const char *from)
8444+{
8445+ return 1;
8446+}
8447+
8448+__u32
8449+gr_acl_handle_link(const struct dentry * new_dentry,
8450+ const struct dentry * parent_dentry,
8451+ const struct vfsmount * parent_mnt,
8452+ const struct dentry * old_dentry,
8453+ const struct vfsmount * old_mnt, const char *to)
8454+{
8455+ return 1;
8456+}
8457+
8458+int
8459+gr_acl_handle_rename(const struct dentry *new_dentry,
8460+ const struct dentry *parent_dentry,
8461+ const struct vfsmount *parent_mnt,
8462+ const struct dentry *old_dentry,
8463+ const struct inode *old_parent_inode,
8464+ const struct vfsmount *old_mnt, const char *newname)
8465+{
8466+ return 1;
8467+}
8468+
8469+__u32
8470+gr_acl_handle_filldir(const struct dentry * dentry,
8471+ const struct vfsmount * mnt, const ino_t ino)
8472+{
8473+ return 1;
8474+}
8475+
8476+int
8477+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
8478+ const time_t shm_createtime, const uid_t cuid, const int shmid)
8479+{
8480+ return 1;
8481+}
8482+
8483+int
8484+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
8485+{
8486+ return 1;
8487+}
8488+
8489+int
8490+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
8491+{
8492+ return 1;
8493+}
8494+
8495+__u32
8496+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
8497+{
8498+ return 1;
8499+}
8500+
8501+__u32
8502+gr_acl_handle_creat(const struct dentry * dentry,
8503+ const struct dentry * p_dentry,
8504+ const struct vfsmount * p_mnt, const int fmode,
8505+ const int imode)
8506+{
8507+ return 1;
8508+}
8509+
8510+void
8511+gr_acl_handle_exit(void)
8512+{
8513+ return;
8514+}
8515+
8516+int
8517+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
8518+{
8519+ return 1;
8520+}
8521+
8522+void
8523+gr_set_role_label(const uid_t uid, const gid_t gid)
8524+{
8525+ return;
8526+}
8527+
8528+int
8529+gr_acl_handle_procpidmem(const struct task_struct *task)
8530+{
8531+ return 0;
8532+}
8533+
8534+int
8535+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
8536+{
8537+ return 1;
8538+}
8539+
8540+int
8541+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
8542+{
8543+ return 1;
8544+}
8545+
8546+void
8547+gr_set_kernel_label(struct task_struct *task)
8548+{
8549+ return;
8550+}
8551diff -urN linux-2.4.22/grsecurity/grsec_exec.c linux-2.4.22/grsecurity/grsec_exec.c
8552--- linux-2.4.22/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
8553+++ linux-2.4.22/grsecurity/grsec_exec.c 2003-09-02 19:29:42.000000000 -0400
8554@@ -0,0 +1,70 @@
8555+#include <linux/kernel.h>
8556+#include <linux/sched.h>
8557+#include <linux/file.h>
8558+#include <linux/fs.h>
8559+#include <linux/types.h>
8560+#include <linux/grdefs.h>
8561+#include <linux/grinternal.h>
8562+#include <linux/capability.h>
8563+
8564+#include <asm/uaccess.h>
8565+
8566+int
8567+gr_handle_nproc(void)
8568+{
8569+#ifdef CONFIG_GRKERNSEC_EXECVE
8570+ if (grsec_enable_execve && current->user &&
8571+ (atomic_read(&current->user->processes) >
8572+ current->rlim[RLIMIT_NPROC].rlim_cur) &&
8573+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
8574+ security_alert(GR_NPROC_MSG, DEFAULTSECARGS);
8575+ return -EAGAIN;
8576+ }
8577+#endif
8578+ return 0;
8579+}
8580+
8581+void
8582+gr_handle_exec_args(struct linux_binprm *bprm, char **argv)
8583+{
8584+#ifdef CONFIG_GRKERNSEC_EXECLOG
8585+ char grarg[64] = { 0 };
8586+ __u8 execlen = 0;
8587+ unsigned int i;
8588+
8589+ if (!((grsec_enable_execlog && grsec_enable_group &&
8590+ in_group_p(grsec_audit_gid))
8591+ || (grsec_enable_execlog && !grsec_enable_group)))
8592+ return;
8593+
8594+ if (unlikely(!argv))
8595+ goto log;
8596+
8597+ for (i = 0; i < bprm->argc && execlen < 62; i++) {
8598+ char *p;
8599+ __u8 len;
8600+
8601+ if (get_user(p, argv + i))
8602+ goto log;
8603+ if (!p)
8604+ goto log;
8605+ len = strnlen_user(p, 62 - execlen);
8606+ if (len > 62 - execlen)
8607+ len = 62 - execlen;
8608+ else if (len > 0)
8609+ len--;
8610+ if (copy_from_user(grarg + execlen, p, len))
8611+ goto log;
8612+ execlen += len;
8613+ *(grarg + execlen) = ' ';
8614+ *(grarg + execlen + 1) = '\0';
8615+ execlen++;
8616+ }
8617+
8618+ log:
8619+ security_audit(GR_EXEC_AUDIT_MSG, gr_to_filename(bprm->file->f_dentry,
8620+ bprm->file->f_vfsmnt),
8621+ grarg, DEFAULTSECARGS);
8622+#endif
8623+ return;
8624+}
8625diff -urN linux-2.4.22/grsecurity/grsec_fifo.c linux-2.4.22/grsecurity/grsec_fifo.c
8626--- linux-2.4.22/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
8627+++ linux-2.4.22/grsecurity/grsec_fifo.c 2003-09-02 19:29:42.000000000 -0400
8628@@ -0,0 +1,24 @@
8629+#include <linux/kernel.h>
8630+#include <linux/sched.h>
8631+#include <linux/fs.h>
8632+#include <linux/file.h>
8633+#include <linux/grinternal.h>
8634+
8635+int
8636+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
8637+ const struct dentry *dir, const int flag, const int acc_mode)
8638+{
8639+#ifdef CONFIG_GRKERNSEC_FIFO
8640+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
8641+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
8642+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
8643+ (current->fsuid != dentry->d_inode->i_uid)) {
8644+ if (!permission(dentry->d_inode, acc_mode))
8645+ security_alert(GR_FIFO_MSG, gr_to_filename(dentry, mnt),
8646+ dentry->d_inode->i_uid,
8647+ dentry->d_inode->i_gid, DEFAULTSECARGS);
8648+ return -EACCES;
8649+ }
8650+#endif
8651+ return 0;
8652+}
8653diff -urN linux-2.4.22/grsecurity/grsec_fork.c linux-2.4.22/grsecurity/grsec_fork.c
8654--- linux-2.4.22/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
8655+++ linux-2.4.22/grsecurity/grsec_fork.c 2003-09-02 19:29:42.000000000 -0400
8656@@ -0,0 +1,14 @@
8657+#include <linux/kernel.h>
8658+#include <linux/sched.h>
8659+#include <linux/grsecurity.h>
8660+#include <linux/grinternal.h>
8661+
8662+void
8663+gr_log_forkfail(const int retval)
8664+{
8665+#ifdef CONFIG_GRKERNSEC_FORKFAIL
8666+ if (grsec_enable_forkfail)
8667+ security_alert(GR_FAILFORK_MSG, retval, DEFAULTSECARGS);
8668+#endif
8669+ return;
8670+}
8671diff -urN linux-2.4.22/grsecurity/grsec_init.c linux-2.4.22/grsecurity/grsec_init.c
8672--- linux-2.4.22/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
8673+++ linux-2.4.22/grsecurity/grsec_init.c 2003-09-02 19:29:42.000000000 -0400
8674@@ -0,0 +1,210 @@
8675+#include <linux/kernel.h>
8676+#include <linux/sched.h>
8677+#include <linux/mm.h>
8678+#include <linux/smp_lock.h>
8679+#include <linux/gracl.h>
8680+#include <linux/slab.h>
8681+
8682+int grsec_enable_link;
8683+int grsec_enable_dmesg;
8684+int grsec_enable_fifo;
8685+int grsec_enable_execve;
8686+int grsec_enable_execlog;
8687+int grsec_enable_signal;
8688+int grsec_enable_forkfail;
8689+int grsec_enable_time;
8690+int grsec_enable_group;
8691+int grsec_audit_gid;
8692+int grsec_enable_chdir;
8693+int grsec_enable_audit_ipc;
8694+int grsec_enable_mount;
8695+int grsec_enable_chroot_findtask;
8696+int grsec_enable_chroot_mount;
8697+int grsec_enable_chroot_shmat;
8698+int grsec_enable_chroot_fchdir;
8699+int grsec_enable_chroot_double;
8700+int grsec_enable_chroot_pivot;
8701+int grsec_enable_chroot_chdir;
8702+int grsec_enable_chroot_chmod;
8703+int grsec_enable_chroot_mknod;
8704+int grsec_enable_chroot_nice;
8705+int grsec_enable_chroot_execlog;
8706+int grsec_enable_chroot_caps;
8707+int grsec_enable_chroot_sysctl;
8708+int grsec_enable_chroot_unix;
8709+int grsec_enable_tpe;
8710+int grsec_tpe_gid;
8711+int grsec_enable_tpe_all;
8712+int grsec_enable_randpid;
8713+int grsec_enable_randid;
8714+int grsec_enable_randisn;
8715+int grsec_enable_randsrc;
8716+int grsec_enable_randrpc;
8717+int grsec_enable_socket_all;
8718+int grsec_socket_all_gid;
8719+int grsec_enable_socket_client;
8720+int grsec_socket_client_gid;
8721+int grsec_enable_socket_server;
8722+int grsec_socket_server_gid;
8723+int grsec_lock;
8724+
8725+spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
8726+unsigned long grsec_alert_wtime = 0;
8727+unsigned long grsec_alert_fyet = 0;
8728+
8729+spinlock_t grsec_alertgood_lock = SPIN_LOCK_UNLOCKED;
8730+unsigned long grsec_alertgood_wtime = 0;
8731+unsigned long grsec_alertgood_fyet = 0;
8732+
8733+spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
8734+
8735+char *gr_shared_page[4][NR_CPUS];
8736+extern struct gr_arg *gr_usermode;
8737+extern unsigned char *gr_system_salt;
8738+extern unsigned char *gr_system_sum;
8739+
8740+void
8741+grsecurity_init(void)
8742+{
8743+ int i, j;
8744+ /* create the per-cpu shared pages */
8745+
8746+ for (j = 0; j < 4; j++) {
8747+ for (i = 0; i < NR_CPUS; i++) {
8748+ gr_shared_page[j][i] = (char *) get_zeroed_page(GFP_KERNEL);
8749+ if (!gr_shared_page[j][i]) {
8750+ panic("Unable to allocate grsecurity shared page");
8751+ return;
8752+ }
8753+ }
8754+ }
8755+
8756+ /* allocate memory for authentication structure */
8757+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
8758+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
8759+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
8760+
8761+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
8762+ panic("Unable to allocate grsecurity authentication structure");
8763+ return;
8764+ }
8765+
8766+#ifndef CONFIG_GRKERNSEC_SYSCTL
8767+ grsec_lock = 1;
8768+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
8769+ grsec_enable_group = 1;
8770+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
8771+#endif
8772+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
8773+ grsec_enable_chdir = 1;
8774+#endif
8775+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8776+ grsec_enable_audit_ipc = 1;
8777+#endif
8778+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
8779+ grsec_enable_mount = 1;
8780+#endif
8781+#ifdef CONFIG_GRKERNSEC_LINK
8782+ grsec_enable_link = 1;
8783+#endif
8784+#ifdef CONFIG_GRKERNSEC_DMESG
8785+ grsec_enable_dmesg = 1;
8786+#endif
8787+#ifdef CONFIG_GRKERNSEC_FIFO
8788+ grsec_enable_fifo = 1;
8789+#endif
8790+#ifdef CONFIG_GRKERNSEC_EXECVE
8791+ grsec_enable_execve = 1;
8792+#endif
8793+#ifdef CONFIG_GRKERNSEC_EXECLOG
8794+ grsec_enable_execlog = 1;
8795+#endif
8796+#ifdef CONFIG_GRKERNSEC_SIGNAL
8797+ grsec_enable_signal = 1;
8798+#endif
8799+#ifdef CONFIG_GRKERNSEC_FORKFAIL
8800+ grsec_enable_forkfail = 1;
8801+#endif
8802+#ifdef CONFIG_GRKERNSEC_TIME
8803+ grsec_enable_time = 1;
8804+#endif
8805+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
8806+ grsec_enable_chroot_findtask = 1;
8807+#endif
8808+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
8809+ grsec_enable_chroot_unix = 1;
8810+#endif
8811+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
8812+ grsec_enable_chroot_mount = 1;
8813+#endif
8814+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
8815+ grsec_enable_chroot_fchdir = 1;
8816+#endif
8817+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
8818+ grsec_enable_chroot_shmat = 1;
8819+#endif
8820+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
8821+ grsec_enable_chroot_double = 1;
8822+#endif
8823+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
8824+ grsec_enable_chroot_pivot = 1;
8825+#endif
8826+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
8827+ grsec_enable_chroot_chdir = 1;
8828+#endif
8829+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
8830+ grsec_enable_chroot_chmod = 1;
8831+#endif
8832+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
8833+ grsec_enable_chroot_mknod = 1;
8834+#endif
8835+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
8836+ grsec_enable_chroot_nice = 1;
8837+#endif
8838+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
8839+ grsec_enable_chroot_execlog = 1;
8840+#endif
8841+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
8842+ grsec_enable_chroot_caps = 1;
8843+#endif
8844+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
8845+ grsec_enable_chroot_sysctl = 1;
8846+#endif
8847+#ifdef CONFIG_GRKERNSEC_TPE
8848+ grsec_enable_tpe = 1;
8849+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
8850+#ifdef CONFIG_GRKERNSEC_TPE_ALL
8851+ grsec_enable_tpe_all = 1;
8852+#endif
8853+#endif
8854+#ifdef CONFIG_GRKERNSEC_RANDPID
8855+ grsec_enable_randpid = 1;
8856+#endif
8857+#ifdef CONFIG_GRKERNSEC_RANDID
8858+ grsec_enable_randid = 1;
8859+#endif
8860+#ifdef CONFIG_GRKERNSEC_RANDISN
8861+ grsec_enable_randisn = 1;
8862+#endif
8863+#ifdef CONFIG_GRKERNSEC_RANDSRC
8864+ grsec_enable_randsrc = 1;
8865+#endif
8866+#ifdef CONFIG_GRKERNSEC_RANDRPC
8867+ grsec_enable_randrpc = 1;
8868+#endif
8869+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
8870+ grsec_enable_socket_all = 1;
8871+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
8872+#endif
8873+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
8874+ grsec_enable_socket_client = 1;
8875+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
8876+#endif
8877+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
8878+ grsec_enable_socket_server = 1;
8879+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
8880+#endif
8881+#endif
8882+
8883+ return;
8884+}
8885diff -urN linux-2.4.22/grsecurity/grsec_ipc.c linux-2.4.22/grsecurity/grsec_ipc.c
8886--- linux-2.4.22/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
8887+++ linux-2.4.22/grsecurity/grsec_ipc.c 2003-09-02 19:29:42.000000000 -0400
8888@@ -0,0 +1,81 @@
8889+#include <linux/kernel.h>
8890+#include <linux/sched.h>
8891+#include <linux/types.h>
8892+#include <linux/ipc.h>
8893+#include <linux/grsecurity.h>
8894+#include <linux/grinternal.h>
8895+
8896+void
8897+gr_log_msgget(const int ret, const int msgflg)
8898+{
8899+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8900+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8901+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
8902+ !grsec_enable_group)) && (ret >= 0)
8903+ && (msgflg & IPC_CREAT))
8904+ security_audit(GR_MSGQ_AUDIT_MSG, DEFAULTSECARGS);
8905+#endif
8906+ return;
8907+}
8908+
8909+void
8910+gr_log_msgrm(const uid_t uid, const uid_t cuid)
8911+{
8912+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8913+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8914+ grsec_enable_audit_ipc) ||
8915+ (grsec_enable_audit_ipc && !grsec_enable_group))
8916+ security_audit(GR_MSGQR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
8917+#endif
8918+ return;
8919+}
8920+
8921+void
8922+gr_log_semget(const int err, const int semflg)
8923+{
8924+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8925+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8926+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
8927+ !grsec_enable_group)) && (err >= 0)
8928+ && (semflg & IPC_CREAT))
8929+ security_audit(GR_SEM_AUDIT_MSG, DEFAULTSECARGS);
8930+#endif
8931+ return;
8932+}
8933+
8934+void
8935+gr_log_semrm(const uid_t uid, const uid_t cuid)
8936+{
8937+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8938+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8939+ grsec_enable_audit_ipc) ||
8940+ (grsec_enable_audit_ipc && !grsec_enable_group))
8941+ security_audit(GR_SEMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
8942+#endif
8943+ return;
8944+}
8945+
8946+void
8947+gr_log_shmget(const int err, const int shmflg, const size_t size)
8948+{
8949+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8950+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8951+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
8952+ !grsec_enable_group)) && (err >= 0)
8953+ && (shmflg & IPC_CREAT))
8954+ security_audit(GR_SHM_AUDIT_MSG, size, DEFAULTSECARGS);
8955+#endif
8956+ return;
8957+}
8958+
8959+void
8960+gr_log_shmrm(const uid_t uid, const uid_t cuid)
8961+{
8962+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
8963+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
8964+ grsec_enable_audit_ipc) ||
8965+ (grsec_enable_audit_ipc && !grsec_enable_group))
8966+ security_audit(GR_SHMR_AUDIT_MSG, uid, cuid, DEFAULTSECARGS);
8967+#endif
8968+ return;
8969+}
8970diff -urN linux-2.4.22/grsecurity/grsec_link.c linux-2.4.22/grsecurity/grsec_link.c
8971--- linux-2.4.22/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
8972+++ linux-2.4.22/grsecurity/grsec_link.c 2003-09-02 19:29:42.000000000 -0400
8973@@ -0,0 +1,41 @@
8974+#include <linux/kernel.h>
8975+#include <linux/sched.h>
8976+#include <linux/fs.h>
8977+#include <linux/file.h>
8978+#include <linux/grinternal.h>
8979+
8980+int
8981+gr_handle_follow_link(const struct inode *parent,
8982+ const struct inode *inode,
8983+ const struct dentry *dentry, const struct vfsmount *mnt)
8984+{
8985+#ifdef CONFIG_GRKERNSEC_LINK
8986+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
8987+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
8988+ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
8989+ security_alert(GR_SYMLINK_MSG, gr_to_filename(dentry, mnt),
8990+ inode->i_uid, inode->i_gid, DEFAULTSECARGS);
8991+ return -EACCES;
8992+ }
8993+#endif
8994+ return 0;
8995+}
8996+
8997+int
8998+gr_handle_hardlink(const struct dentry *dentry,
8999+ const struct vfsmount *mnt,
9000+ struct inode *inode, const int mode, const char *to)
9001+{
9002+#ifdef CONFIG_GRKERNSEC_LINK
9003+ if (grsec_enable_link && current->fsuid != inode->i_uid &&
9004+ (!S_ISREG(mode) || (mode & S_ISUID) ||
9005+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
9006+ (permission(inode, MAY_READ | MAY_WRITE))) &&
9007+ !capable(CAP_FOWNER) && current->uid) {
9008+ security_alert(GR_HARDLINK_MSG, gr_to_filename(dentry, mnt),
9009+ inode->i_uid, inode->i_gid, to, DEFAULTSECARGS);
9010+ return -EPERM;
9011+ }
9012+#endif
9013+ return 0;
9014+}
9015diff -urN linux-2.4.22/grsecurity/grsec_mem.c linux-2.4.22/grsecurity/grsec_mem.c
9016--- linux-2.4.22/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
9017+++ linux-2.4.22/grsecurity/grsec_mem.c 2003-09-02 19:29:42.000000000 -0400
9018@@ -0,0 +1,54 @@
9019+#include <linux/kernel.h>
9020+#include <linux/sched.h>
9021+#include <linux/mm.h>
9022+#include <linux/grinternal.h>
9023+
9024+void
9025+gr_handle_ioperm(void)
9026+{
9027+ security_alert(GR_IOPERM_MSG, DEFAULTSECARGS);
9028+ return;
9029+}
9030+
9031+void
9032+gr_handle_iopl(void)
9033+{
9034+ security_alert(GR_IOPL_MSG, DEFAULTSECARGS);
9035+ return;
9036+}
9037+
9038+void
9039+gr_handle_mem_write(void)
9040+{
9041+ security_alert(GR_MEM_WRITE_MSG, DEFAULTSECARGS);
9042+ return;
9043+}
9044+
9045+void
9046+gr_handle_kmem_write(void)
9047+{
9048+ security_alert(GR_KMEM_MSG, DEFAULTSECARGS);
9049+ return;
9050+}
9051+
9052+void
9053+gr_handle_open_port(void)
9054+{
9055+ security_alert(GR_PORT_OPEN_MSG, DEFAULTSECARGS);
9056+ return;
9057+}
9058+
9059+int
9060+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
9061+{
9062+ if (offset < __pa(high_memory) &&
9063+ (pgprot_val(vma->vm_page_prot) & PROT_WRITE) &&
9064+ !(offset == 0xf0000 && ((vma->vm_end - vma->vm_start) <= 0x10000)) &&
9065+ !(offset == 0xa0000 && ((vma->vm_end - vma->vm_start) <= 0x20000))) {
9066+ security_alert(GR_MEM_MMAP_MSG, DEFAULTSECARGS);
9067+ return -EPERM;
9068+ } else if (offset < __pa(high_memory))
9069+ vma->vm_flags &= ~VM_MAYWRITE;
9070+
9071+ return 0;
9072+}
9073diff -urN linux-2.4.22/grsecurity/grsec_mount.c linux-2.4.22/grsecurity/grsec_mount.c
9074--- linux-2.4.22/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
9075+++ linux-2.4.22/grsecurity/grsec_mount.c 2003-09-02 19:29:42.000000000 -0400
9076@@ -0,0 +1,34 @@
9077+#include <linux/kernel.h>
9078+#include <linux/sched.h>
9079+#include <linux/grsecurity.h>
9080+#include <linux/grinternal.h>
9081+
9082+void
9083+gr_log_remount(const char *devname, const int retval)
9084+{
9085+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
9086+ if (grsec_enable_mount && (retval >= 0))
9087+ security_audit(GR_REMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
9088+#endif
9089+ return;
9090+}
9091+
9092+void
9093+gr_log_unmount(const char *devname, const int retval)
9094+{
9095+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
9096+ if (grsec_enable_mount && (retval >= 0))
9097+ security_audit(GR_UNMOUNT_AUDIT_MSG, devname, DEFAULTSECARGS);
9098+#endif
9099+ return;
9100+}
9101+
9102+void
9103+gr_log_mount(const char *from, const char *to, const int retval)
9104+{
9105+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
9106+ if (grsec_enable_mount && (retval >= 0))
9107+ security_audit(GR_MOUNT_AUDIT_MSG, from, to, DEFAULTSECARGS);
9108+#endif
9109+ return;
9110+}
9111diff -urN linux-2.4.22/grsecurity/grsec_rand.c linux-2.4.22/grsecurity/grsec_rand.c
9112--- linux-2.4.22/grsecurity/grsec_rand.c 1969-12-31 19:00:00.000000000 -0500
9113+++ linux-2.4.22/grsecurity/grsec_rand.c 2003-09-02 19:29:42.000000000 -0400
9114@@ -0,0 +1,36 @@
9115+#include <linux/kernel.h>
9116+#include <linux/sched.h>
9117+#include <linux/smp_lock.h>
9118+#include <linux/grsecurity.h>
9119+#include <linux/grinternal.h>
9120+
9121+extern int last_pid;
9122+
9123+int
9124+gr_random_pid(spinlock_t * pid_lock)
9125+{
9126+#ifdef CONFIG_GRKERNSEC_RANDPID
9127+ struct task_struct *p;
9128+ int pid;
9129+
9130+ if (grsec_enable_randpid && current->fs->root) {
9131+ read_lock(&tasklist_lock);
9132+ spin_lock(pid_lock);
9133+
9134+ repeater:
9135+
9136+ pid = 1 + (get_random_long() % PID_MAX);
9137+
9138+ for_each_task(p) {
9139+ if (p->pid == pid || p->pgrp == pid ||
9140+ p->tgid == pid || p->session == pid)
9141+ goto repeater;
9142+ }
9143+ last_pid = pid;
9144+ spin_unlock(pid_lock);
9145+ read_unlock(&tasklist_lock);
9146+ return pid;
9147+ }
9148+#endif
9149+ return 0;
9150+}
9151diff -urN linux-2.4.22/grsecurity/grsec_sig.c linux-2.4.22/grsecurity/grsec_sig.c
9152--- linux-2.4.22/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
9153+++ linux-2.4.22/grsecurity/grsec_sig.c 2003-09-02 19:29:42.000000000 -0400
9154@@ -0,0 +1,47 @@
9155+#include <linux/kernel.h>
9156+#include <linux/sched.h>
9157+#include <linux/grinternal.h>
9158+
9159+void
9160+gr_log_signal(const int sig, const struct task_struct *t)
9161+{
9162+#ifdef CONFIG_GRKERNSEC_SIGNAL
9163+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
9164+ (sig == SIGABRT) || (sig == SIGBUS))) {
9165+ if (t->pid == current->pid) {
9166+ security_alert_good(GR_UNISIGLOG_MSG, sig,
9167+ DEFAULTSECARGS);
9168+ } else {
9169+ security_alert_good(GR_DUALSIGLOG_MSG, sig,
9170+ gr_task_fullpath(t), t->comm,
9171+ t->pid, t->uid, t->euid, t->gid,
9172+ t->egid, gr_parent_task_fullpath(t),
9173+ t->p_pptr->comm,
9174+ t->p_pptr->pid, t->p_pptr->uid,
9175+ t->p_pptr->euid, t->p_pptr->gid,
9176+ t->p_pptr->egid, DEFAULTSECARGS);
9177+ }
9178+ }
9179+#endif
9180+ return;
9181+}
9182+
9183+int
9184+gr_handle_signal(const struct task_struct *p, const int sig)
9185+{
9186+#ifdef CONFIG_GRKERNSEC
9187+ if (current->pid > 1 && gr_check_protected_task(p)) {
9188+ security_alert(GR_SIG_ACL_MSG, sig, gr_task_fullpath(p),
9189+ p->comm, p->pid, p->uid,
9190+ p->euid, p->gid, p->egid,
9191+ gr_parent_task_fullpath(p), p->p_pptr->comm,
9192+ p->p_pptr->pid, p->p_pptr->uid,
9193+ p->p_pptr->euid, p->p_pptr->gid,
9194+ p->p_pptr->egid, DEFAULTSECARGS);
9195+ return -EPERM;
9196+ } else if (gr_pid_is_chrooted(p)) {
9197+ return -EPERM;
9198+ }
9199+#endif
9200+ return 0;
9201+}
9202diff -urN linux-2.4.22/grsecurity/grsec_sock.c linux-2.4.22/grsecurity/grsec_sock.c
9203--- linux-2.4.22/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
9204+++ linux-2.4.22/grsecurity/grsec_sock.c 2003-09-02 19:29:42.000000000 -0400
9205@@ -0,0 +1,123 @@
9206+#include <linux/kernel.h>
9207+#include <linux/sched.h>
9208+#include <linux/file.h>
9209+#include <linux/net.h>
9210+#include <net/sock.h>
9211+#include <linux/grsecurity.h>
9212+#include <linux/grinternal.h>
9213+#include <linux/gracl.h>
9214+
9215+void
9216+gr_attach_curr_ip(const struct sock *sk)
9217+{
9218+#ifdef CONFIG_GRKERNSEC
9219+ struct task_struct *p;
9220+ unsigned int i;
9221+ struct inode *inode;
9222+ struct file *filp;
9223+ struct socket *connect_sock;
9224+
9225+ if (unlikely(sk->protocol != IPPROTO_TCP))
9226+ return;
9227+
9228+ read_lock(&tasklist_lock);
9229+ for_each_task(p) {
9230+ if (!p->used_connect)
9231+ continue;
9232+ task_lock(p);
9233+ if (unlikely(!p->files)) {
9234+ task_unlock(p);
9235+ continue;
9236+ }
9237+ read_lock(&p->files->file_lock);
9238+ for (i = 0; i < p->files->max_fds; i++) {
9239+ filp = fcheck_files(p->files, i);
9240+ if (likely(!filp))
9241+ continue;
9242+ inode = filp->f_dentry->d_inode;
9243+ if (likely(!inode || !inode->i_sock))
9244+ continue;
9245+ connect_sock = &inode->u.socket_i;
9246+ if (unlikely(!connect_sock ||
9247+ connect_sock->sk->protocol != IPPROTO_TCP))
9248+ continue;
9249+ if (unlikely(sk->rcv_saddr == connect_sock->sk->daddr &&
9250+ sk->daddr == connect_sock->sk->rcv_saddr &&
9251+ ntohs(sk->sport) ==
9252+ ntohs(connect_sock->sk->dport)
9253+ && ntohs(sk->dport) ==
9254+ ntohs(connect_sock->sk->sport))) {
9255+ current->curr_ip = p->curr_ip;
9256+ current->used_accept = 1;
9257+ read_unlock(&p->files->file_lock);
9258+ task_unlock(p);
9259+ read_unlock(&tasklist_lock);
9260+ return;
9261+ }
9262+ }
9263+ read_unlock(&p->files->file_lock);
9264+ task_unlock(p);
9265+ }
9266+ read_unlock(&tasklist_lock);
9267+
9268+ current->curr_ip = sk->daddr;
9269+ current->used_accept = 1;
9270+#endif
9271+ return;
9272+}
9273+
9274+int
9275+gr_handle_sock_all(const int family, const int type, const int protocol)
9276+{
9277+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
9278+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
9279+ (family != AF_UNIX) && (family != AF_LOCAL)) {
9280+ security_alert(GR_SOCK_MSG, family, type, protocol,
9281+ DEFAULTSECARGS);
9282+ return -EACCES;
9283+ }
9284+#endif
9285+ return 0;
9286+}
9287+
9288+int
9289+gr_handle_sock_server(const struct sockaddr *sck)
9290+{
9291+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
9292+ if (grsec_enable_socket_server &&
9293+ in_group_p(grsec_socket_server_gid) &&
9294+ sck && (sck->sa_family != AF_UNIX) &&
9295+ (sck->sa_family != AF_LOCAL)) {
9296+ security_alert(GR_BIND_MSG, DEFAULTSECARGS);
9297+ return -EACCES;
9298+ }
9299+#endif
9300+ return 0;
9301+}
9302+
9303+int
9304+gr_handle_sock_client(const struct sockaddr *sck)
9305+{
9306+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
9307+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
9308+ sck && (sck->sa_family != AF_UNIX) &&
9309+ (sck->sa_family != AF_LOCAL)) {
9310+ security_alert(GR_CONNECT_MSG, DEFAULTSECARGS);
9311+ return -EACCES;
9312+ }
9313+#endif
9314+ return 0;
9315+}
9316+
9317+__u32
9318+gr_cap_rtnetlink(void)
9319+{
9320+#ifdef CONFIG_GRKERNSEC
9321+ if (!gr_acl_is_enabled())
9322+ return current->cap_effective;
9323+ else
9324+ return (current->cap_effective & ~(current->acl->cap_lower));
9325+#else
9326+ return current->cap_effective;
9327+#endif
9328+}
9329diff -urN linux-2.4.22/grsecurity/grsec_sysctl.c linux-2.4.22/grsecurity/grsec_sysctl.c
9330--- linux-2.4.22/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
9331+++ linux-2.4.22/grsecurity/grsec_sysctl.c 2003-09-02 19:29:42.000000000 -0400
9332@@ -0,0 +1,16 @@
9333+#include <linux/kernel.h>
9334+#include <linux/sched.h>
9335+#include <linux/sysctl.h>
9336+#include <linux/grinternal.h>
9337+
9338+int
9339+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
9340+{
9341+#ifdef CONFIG_GRKERNSEC_SYSCTL
9342+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
9343+ security_alert(GR_SYSCTL_MSG, name, DEFAULTSECARGS);
9344+ return -EACCES;
9345+ }
9346+#endif
9347+ return 0;
9348+}
9349diff -urN linux-2.4.22/grsecurity/grsec_time.c linux-2.4.22/grsecurity/grsec_time.c
9350--- linux-2.4.22/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
9351+++ linux-2.4.22/grsecurity/grsec_time.c 2003-09-02 19:29:42.000000000 -0400
9352@@ -0,0 +1,13 @@
9353+#include <linux/kernel.h>
9354+#include <linux/sched.h>
9355+#include <linux/grinternal.h>
9356+
9357+void
9358+gr_log_timechange(void)
9359+{
9360+#ifdef CONFIG_GRKERNSEC_TIME
9361+ if (grsec_enable_time)
9362+ security_alert_good(GR_TIME_MSG, DEFAULTSECARGS);
9363+#endif
9364+ return;
9365+}
9366diff -urN linux-2.4.22/grsecurity/grsec_tpe.c linux-2.4.22/grsecurity/grsec_tpe.c
9367--- linux-2.4.22/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
9368+++ linux-2.4.22/grsecurity/grsec_tpe.c 2003-09-02 19:29:42.000000000 -0400
9369@@ -0,0 +1,35 @@
9370+#include <linux/kernel.h>
9371+#include <linux/sched.h>
9372+#include <linux/file.h>
9373+#include <linux/fs.h>
9374+#include <linux/grinternal.h>
9375+
9376+extern int gr_acl_tpe_check(void);
9377+
9378+int
9379+gr_tpe_allow(const struct file *file)
9380+{
9381+#ifdef CONFIG_GRKERNSEC
9382+ struct inode *inode = file->f_dentry->d_parent->d_inode;
9383+
9384+ if (current->uid && ((grsec_enable_tpe && in_group_p(grsec_tpe_gid)) || gr_acl_tpe_check()) &&
9385+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
9386+ (inode->i_mode & S_IWOTH))))) {
9387+ security_alert(GR_EXEC_TPE_MSG,
9388+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
9389+ DEFAULTSECARGS);
9390+ return 0;
9391+ }
9392+#ifdef CONFIG_GRKERNSEC_TPE_ALL
9393+ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
9394+ ((inode->i_uid && (inode->i_uid != current->uid)) ||
9395+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
9396+ security_alert(GR_EXEC_TPE_MSG,
9397+ gr_to_filename(file->f_dentry, file->f_vfsmnt),
9398+ DEFAULTSECARGS);
9399+ return 0;
9400+ }
9401+#endif
9402+#endif
9403+ return 1;
9404+}
9405diff -urN linux-2.4.22/grsecurity/grsum.c linux-2.4.22/grsecurity/grsum.c
9406--- linux-2.4.22/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
9407+++ linux-2.4.22/grsecurity/grsum.c 2003-09-02 19:29:42.000000000 -0400
9408@@ -0,0 +1,59 @@
9409+#include <linux/kernel.h>
9410+#include <linux/sched.h>
9411+#include <linux/mm.h>
9412+#include <asm/scatterlist.h>
9413+#include <linux/crypto.h>
9414+#include <linux/gracl.h>
9415+
9416+
9417+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
9418+#error "crypto and sha256 must be built into the kernel"
9419+#endif
9420+
9421+int
9422+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
9423+{
9424+ char *p;
9425+ struct crypto_tfm *tfm;
9426+ unsigned char temp_sum[GR_SHA_LEN];
9427+ struct scatterlist sg[2];
9428+ volatile int retval = 0;
9429+ volatile int dummy = 0;
9430+ unsigned int i;
9431+
9432+ tfm = crypto_alloc_tfm("sha256", 0);
9433+ if (tfm == NULL) {
9434+ /* should never happen, since sha256 should be built in */
9435+ return 1;
9436+ }
9437+
9438+ crypto_digest_init(tfm);
9439+
9440+ p = salt;
9441+ sg[0].page = virt_to_page(p);
9442+ sg[0].offset = ((long) p & ~PAGE_MASK);
9443+ sg[0].length = GR_SALT_LEN;
9444+
9445+ crypto_digest_update(tfm, sg, 1);
9446+
9447+ p = entry->pw;
9448+ sg[0].page = virt_to_page(p);
9449+ sg[0].offset = ((long) p & ~PAGE_MASK);
9450+ sg[0].length = strlen(entry->pw);
9451+
9452+ crypto_digest_update(tfm, sg, 1);
9453+
9454+ crypto_digest_final(tfm, temp_sum);
9455+
9456+ memset(entry->pw, 0, GR_PW_LEN);
9457+
9458+ for (i = 0; i < GR_SHA_LEN; i++)
9459+ if (sum[i] != temp_sum[i])
9460+ retval = 1;
9461+ else
9462+ dummy = 1; // waste a cycle
9463+
9464+ crypto_free_tfm(tfm);
9465+
9466+ return retval;
9467+}
9468diff -urN linux-2.4.22/grsecurity/obsd_rand.c linux-2.4.22/grsecurity/obsd_rand.c
9469--- linux-2.4.22/grsecurity/obsd_rand.c 1969-12-31 19:00:00.000000000 -0500
9470+++ linux-2.4.22/grsecurity/obsd_rand.c 2003-09-02 19:29:42.000000000 -0400
9471@@ -0,0 +1,195 @@
9472+
9473+/*
9474+ * Copyright (c) 1996, 1997, 2000-2002 Michael Shalayeff.
9475+ *
9476+ * Version 1.89, last modified 19-Sep-99
9477+ *
9478+ * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999.
9479+ * All rights reserved.
9480+ *
9481+ * Copyright 1998 Niels Provos <provos@citi.umich.edu>
9482+ * All rights reserved.
9483+ * Theo de Raadt <deraadt@openbsd.org> came up with the idea of using
9484+ * such a mathematical system to generate more random (yet non-repeating)
9485+ * ids to solve the resolver/named problem. But Niels designed the
9486+ * actual system based on the constraints.
9487+ *
9488+ * Redistribution and use in source and binary forms, with or without
9489+ * modification, are permitted provided that the following conditions
9490+ * are met:
9491+ * 1. Redistributions of source code must retain the above copyright
9492+ * notice, this list of conditions and the following disclaimer,
9493+ * 2. Redistributions in binary form must reproduce the above copyright
9494+ * notice, this list of conditions and the following disclaimer in the
9495+ * documentation and/or other materials provided with the distribution.
9496+ * 3. All advertising materials mentioning features or use of this software
9497+ * must display the following acknowledgement:
9498+ * This product includes software developed by Niels Provos.
9499+ * 4. The name of the author may not be used to endorse or promote products
9500+ * derived from this software without specific prior written permission.
9501+ *
9502+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
9503+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
9504+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
9505+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
9506+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9507+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
9508+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
9509+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
9510+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
9511+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9512+ */
9513+
9514+#include <linux/kernel.h>
9515+#include <linux/sched.h>
9516+#include <linux/timer.h>
9517+#include <linux/smp_lock.h>
9518+#include <linux/random.h>
9519+#include <linux/grsecurity.h>
9520+
9521+#define RU_OUT 180
9522+#define RU_MAX 30000
9523+#define RU_GEN 2
9524+#define RU_N 32749
9525+#define RU_AGEN 7
9526+#define RU_M 31104
9527+#define PFAC_N 3
9528+const static __u16 pfacts[PFAC_N] = { 2, 3, 2729 };
9529+
9530+static __u16 ru_x;
9531+static __u16 ru_seed, ru_seed2;
9532+static __u16 ru_a, ru_b;
9533+static __u16 ru_g;
9534+static __u16 ru_counter = 0;
9535+static __u16 ru_msb = 0;
9536+static unsigned long ru_reseed = 0;
9537+static __u32 tmp;
9538+
9539+#define TCP_RNDISS_ROUNDS 15
9540+#define TCP_RNDISS_OUT 7200
9541+#define TCP_RNDISS_MAX 30000
9542+
9543+static __u8 tcp_rndiss_sbox[NR_CPUS][128];
9544+static __u16 tcp_rndiss_msb[NR_CPUS];
9545+static __u16 tcp_rndiss_cnt[NR_CPUS];
9546+static unsigned long tcp_rndiss_reseed[NR_CPUS];
9547+
9548+static __u16 pmod(__u16, __u16, __u16);
9549+static void ip_initid(void);
9550+__u16 ip_randomid(void);
9551+
9552+static __u16
9553+pmod(__u16 gen, __u16 exp, __u16 mod)
9554+{
9555+ __u16 s, t, u;
9556+
9557+ s = 1;
9558+ t = gen;
9559+ u = exp;
9560+
9561+ while (u) {
9562+ if (u & 1)
9563+ s = (s * t) % mod;
9564+ u >>= 1;
9565+ t = (t * t) % mod;
9566+ }
9567+ return (s);
9568+}
9569+
9570+static void
9571+ip_initid(void)
9572+{
9573+ __u16 j, i;
9574+ int noprime = 1;
9575+
9576+ ru_x = ((tmp = get_random_long()) & 0xFFFF) % RU_M;
9577+
9578+ ru_seed = (tmp >> 16) & 0x7FFF;
9579+ ru_seed2 = get_random_long() & 0x7FFF;
9580+
9581+ ru_b = ((tmp = get_random_long()) & 0xfffe) | 1;
9582+ ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M);
9583+ while (ru_b % 3 == 0)
9584+ ru_b += 2;
9585+
9586+ j = (tmp = get_random_long()) % RU_N;
9587+ tmp = tmp >> 16;
9588+
9589+ while (noprime) {
9590+ for (i = 0; i < PFAC_N; i++)
9591+ if (j % pfacts[i] == 0)
9592+ break;
9593+
9594+ if (i >= PFAC_N)
9595+ noprime = 0;
9596+ else
9597+ j = (j + 1) % RU_N;
9598+ }
9599+
9600+ ru_g = pmod(RU_GEN, j, RU_N);
9601+ ru_counter = 0;
9602+
9603+ ru_reseed = xtime.tv_sec + RU_OUT;
9604+ ru_msb = ru_msb == 0x8000 ? 0 : 0x8000;
9605+}
9606+
9607+__u16
9608+ip_randomid(void)
9609+{
9610+ int i, n;
9611+
9612+ if (ru_counter >= RU_MAX || time_after(xtime.tv_sec, ru_reseed))
9613+ ip_initid();
9614+
9615+ if (!tmp)
9616+ tmp = get_random_long();
9617+
9618+ n = tmp & 0x3;
9619+ tmp = tmp >> 2;
9620+ if (ru_counter + n >= RU_MAX)
9621+ ip_initid();
9622+ for (i = 0; i <= n; i++)
9623+ ru_x = (ru_a * ru_x + ru_b) % RU_M;
9624+ ru_counter += i;
9625+
9626+ return ((ru_seed ^ pmod(ru_g, ru_seed2 ^ ru_x, RU_N)) | ru_msb);
9627+}
9628+
9629+__u16
9630+tcp_rndiss_encrypt(__u16 val)
9631+{
9632+ __u16 sum = 0, i;
9633+ int cpu = smp_processor_id();
9634+
9635+ for (i = 0; i < TCP_RNDISS_ROUNDS; i++) {
9636+ sum += 0x79b9;
9637+ val ^= ((__u16) tcp_rndiss_sbox[cpu][(val ^ sum) ^ 0x7f]) << 7;
9638+ val = ((val & 0xff) << 7) | (val >> 8);
9639+ }
9640+
9641+ return val;
9642+}
9643+
9644+static void
9645+tcp_rndiss_init(void)
9646+{
9647+ int cpu = smp_processor_id();
9648+
9649+ get_random_bytes(tcp_rndiss_sbox[cpu], sizeof (tcp_rndiss_sbox));
9650+ tcp_rndiss_reseed[cpu] = xtime.tv_sec + TCP_RNDISS_OUT;
9651+ tcp_rndiss_msb[cpu] = tcp_rndiss_msb[cpu] == 0x8000 ? 0 : 0x8000;
9652+ tcp_rndiss_cnt[cpu] = 0;
9653+}
9654+
9655+__u32
9656+ip_randomisn(void)
9657+{
9658+ int cpu = smp_processor_id();
9659+
9660+ if (tcp_rndiss_cnt[cpu] >= TCP_RNDISS_MAX ||
9661+ time_after(xtime.tv_sec, tcp_rndiss_reseed[cpu]))
9662+ tcp_rndiss_init();
9663+
9664+ return (((tcp_rndiss_encrypt(tcp_rndiss_cnt[cpu]++) |
9665+ tcp_rndiss_msb[cpu]) << 16) | (get_random_long() & 0x7fff));
9666+}
9667diff -urN linux-2.4.22/include/linux/fs.h linux-2.4.22/include/linux/fs.h
9668--- linux-2.4.22/include/linux/fs.h 2003-09-01 22:19:02.000000000 -0400
9669+++ linux-2.4.22/include/linux/fs.h 2003-09-02 19:33:29.000000000 -0400
9670@@ -1087,7 +1087,7 @@
9671
9672 asmlinkage long sys_open(const char *, int, int);
9673 asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */
9674-extern int do_truncate(struct dentry *, loff_t start);
9675+extern int do_truncate(struct dentry *, loff_t start, struct vfsmount *);
9676
9677 extern struct file *filp_open(const char *, int, int);
9678 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
9679diff -urN linux-2.4.22/include/linux/gracl.h linux-2.4.22/include/linux/gracl.h
9680--- linux-2.4.22/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
9681+++ linux-2.4.22/include/linux/gracl.h 2003-09-02 19:40:47.000000000 -0400
9682@@ -0,0 +1,212 @@
9683+#ifndef GR_ACL_H
9684+#define GR_ACL_H
9685+#endif
9686+#include <linux/grdefs.h>
9687+#include <linux/resource.h>
9688+
9689+#include <asm/resource.h>
9690+
9691+/* * * * * * * * * * * * * * * * * * * * *
9692+ * grsecurity ACL System
9693+ * Main header file
9694+ * Purpose: define most gracl data structures
9695+ * * * * * * * * * * * * * * * * * * * * */
9696+
9697+/* Major status information */
9698+
9699+#define GR_VERSION "grsecurity 2.0"
9700+
9701+enum {
9702+
9703+ SHUTDOWN = 0,
9704+ ENABLE = 1,
9705+ SPROLE = 2,
9706+ RELOAD = 3,
9707+ SEGVMOD = 4,
9708+ STATUS = 5,
9709+ UNSPROLE = 6
9710+};
9711+
9712+/* Password setup definitions
9713+ * kernel/grhash.c */
9714+enum {
9715+ GR_PW_LEN = 128,
9716+ GR_SALT_LEN = 16,
9717+ GR_SHA_LEN = 32,
9718+};
9719+
9720+enum {
9721+ GR_SPROLE_LEN = 64,
9722+};
9723+
9724+/* Begin Data Structures */
9725+
9726+struct sprole_pw {
9727+ unsigned char *rolename;
9728+ unsigned char salt[GR_SALT_LEN];
9729+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
9730+};
9731+
9732+struct name_entry {
9733+ ino_t inode;
9734+ kdev_t device;
9735+ char *name;
9736+ __u16 len;
9737+};
9738+
9739+struct acl_role_db {
9740+ struct acl_role_label **r_hash;
9741+ __u32 r_size;
9742+};
9743+
9744+struct name_db {
9745+ struct name_entry **n_hash;
9746+ __u32 n_size;
9747+};
9748+
9749+struct crash_uid {
9750+ uid_t uid;
9751+ unsigned long expires;
9752+};
9753+
9754+/* Userspace Grsecurity ACL data structures */
9755+struct acl_subject_label {
9756+ char *filename;
9757+ ino_t inode;
9758+ kdev_t device;
9759+ __u32 mode;
9760+ __u32 cap_raise;
9761+ __u32 cap_lower;
9762+
9763+ struct rlimit res[RLIM_NLIMITS + 1];
9764+ __u16 resmask;
9765+
9766+ __u32 ip_proto[8];
9767+ __u32 ip_type;
9768+ struct acl_ip_label **ips;
9769+ __u32 ip_num;
9770+
9771+ __u32 crashes;
9772+ unsigned long expires;
9773+
9774+ struct acl_subject_label *parent_subject;
9775+ struct acl_object_label *proc_object;
9776+ struct acl_ip_label *ip_object;
9777+ struct acl_subject_label *prev;
9778+ struct acl_subject_label *next;
9779+
9780+ struct acl_object_label **obj_hash;
9781+ __u32 obj_hash_size;
9782+};
9783+
9784+struct role_allowed_ip {
9785+ __u32 addr;
9786+ __u32 netmask;
9787+
9788+ struct role_allowed_ip *prev;
9789+ struct role_allowed_ip *next;
9790+};
9791+
9792+struct role_transition {
9793+ char *rolename;
9794+
9795+ struct role_transition *prev;
9796+ struct role_transition *next;
9797+};
9798+
9799+struct acl_role_label {
9800+ char *rolename;
9801+ uid_t uidgid;
9802+ __u16 roletype;
9803+
9804+ __u16 auth_attempts;
9805+ unsigned long expires;
9806+
9807+ struct acl_subject_label *root_label;
9808+ struct acl_subject_label *proc_subject;
9809+
9810+ struct acl_role_label *prev;
9811+ struct acl_role_label *next;
9812+
9813+ struct role_transition *transitions;
9814+ struct role_allowed_ip *allowed_ips;
9815+ struct acl_subject_label **subj_hash;
9816+ __u32 subj_hash_size;
9817+};
9818+
9819+struct user_acl_role_db {
9820+ struct acl_role_label **r_table;
9821+ __u32 r_entries; /* number of entries in table */
9822+ __u32 s_entries; /* total number of subject acls */
9823+ __u32 i_entries; /* total number of ip acls */
9824+ __u32 o_entries; /* Total number of object acls */
9825+ __u32 a_entries; /* total number of allowed ips */
9826+ __u32 t_entries; /* total number of transitions */
9827+};
9828+
9829+struct acl_object_label {
9830+ char *filename;
9831+ ino_t inode;
9832+ kdev_t device;
9833+ __u32 mode;
9834+
9835+ struct acl_subject_label *nested;
9836+
9837+ /* next two structures not used */
9838+
9839+ struct acl_object_label *prev;
9840+ struct acl_object_label *next;
9841+};
9842+
9843+struct acl_ip_label {
9844+ __u32 addr;
9845+ __u32 netmask;
9846+ __u16 low, high;
9847+ __u8 mode;
9848+ __u32 type;
9849+ __u32 proto[8];
9850+
9851+ /* next two structures not used */
9852+
9853+ struct acl_ip_label *prev;
9854+ struct acl_ip_label *next;
9855+};
9856+
9857+struct gr_arg {
9858+ struct user_acl_role_db role_db;
9859+ unsigned char pw[GR_PW_LEN];
9860+ unsigned char salt[GR_SALT_LEN];
9861+ unsigned char sum[GR_SHA_LEN];
9862+ unsigned char sp_role[GR_SPROLE_LEN];
9863+ struct sprole_pw *sprole_pws;
9864+ __u16 num_sprole_pws;
9865+ kdev_t segv_device;
9866+ ino_t segv_inode;
9867+ uid_t segv_uid;
9868+ __u16 mode;
9869+};
9870+
9871+/* End Data Structures Section */
9872+
9873+/* Hash functions generated by empirical testing by Brad Spengler
9874+ Makes good use of the low bits of the inode. Generally 0-1 times
9875+ in loop for successful match. 0-3 for unsuccessful match.
9876+ Shift/add algorithm with modulus of table size and an XOR*/
9877+
9878+static __inline__ unsigned long
9879+rhash(const uid_t uid, const __u16 type, const unsigned long sz)
9880+{
9881+ return (((uid << type) + (uid ^ type)) % sz);
9882+}
9883+
9884+static __inline__ unsigned long
9885+fhash(const ino_t ino, const kdev_t dev, const unsigned long sz)
9886+{
9887+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
9888+}
9889+
9890+static __inline__ unsigned long
9891+nhash(const char *name, const __u16 len, const unsigned long sz)
9892+{
9893+ return full_name_hash(name, len) % sz;
9894+}
9895diff -urN linux-2.4.22/include/linux/gralloc.h linux-2.4.22/include/linux/gralloc.h
9896--- linux-2.4.22/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
9897+++ linux-2.4.22/include/linux/gralloc.h 2003-09-02 19:29:42.000000000 -0400
9898@@ -0,0 +1,8 @@
9899+#ifndef __GRALLOC_H
9900+#define __GRALLOC_H
9901+
9902+void acl_free_all(void);
9903+int acl_alloc_stack_init(unsigned long size);
9904+void *acl_alloc(unsigned long len);
9905+
9906+#endif
9907diff -urN linux-2.4.22/include/linux/grdefs.h linux-2.4.22/include/linux/grdefs.h
9908--- linux-2.4.22/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
9909+++ linux-2.4.22/include/linux/grdefs.h 2003-09-02 19:29:42.000000000 -0400
9910@@ -0,0 +1,104 @@
9911+#ifndef GRDEFS_H
9912+#define GRDEFS_H
9913+
9914+/* Begin grsecurity status declarations */
9915+
9916+enum {
9917+ GR_READY = 0x01,
9918+ GR_STATUS_INIT = 0x00 // disabled state
9919+};
9920+
9921+/* Begin ACL declarations */
9922+
9923+/* Role flags */
9924+
9925+enum {
9926+ GR_ROLE_USER = 0x0001,
9927+ GR_ROLE_GROUP = 0x0002,
9928+ GR_ROLE_DEFAULT = 0x0004,
9929+ GR_ROLE_SPECIAL = 0x0008,
9930+ GR_ROLE_AUTH = 0x0010,
9931+ GR_ROLE_NOPW = 0x0020,
9932+ GR_ROLE_GOD = 0x0040,
9933+ GR_ROLE_LEARN = 0x0080,
9934+ GR_ROLE_TPE = 0x0100
9935+};
9936+
9937+/* ACL Subject and Object mode flags */
9938+enum {
9939+ GR_DELETED = 0x00000080
9940+};
9941+
9942+/* ACL Object-only mode flags */
9943+enum {
9944+ GR_READ = 0x00000001,
9945+ GR_APPEND = 0x00000002,
9946+ GR_WRITE = 0x00000004,
9947+ GR_EXEC = 0x00000008,
9948+ GR_FIND = 0x00000010,
9949+ GR_INHERIT = 0x00000040,
9950+ GR_PTRACERD = 0x00000100,
9951+ GR_SETID = 0x00000200,
9952+ GR_CREATE = 0x00000400,
9953+ GR_DELETE = 0x00000800,
9954+ GR_AUDIT_READ = 0x00001000,
9955+ GR_AUDIT_APPEND = 0x00002000,
9956+ GR_AUDIT_WRITE = 0x0004000,
9957+ GR_AUDIT_EXEC = 0x00008000,
9958+ GR_AUDIT_FIND = 0x00010000,
9959+ GR_AUDIT_INHERIT = 0x00020000,
9960+ GR_AUDIT_SETID = 0x00400000,
9961+ GR_AUDIT_CREATE = 0x00800000,
9962+ GR_AUDIT_DELETE = 0x01000000,
9963+ GR_SUPPRESS = 0x02000000,
9964+ GR_NOLEARN = 0x04000000
9965+};
9966+
9967+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
9968+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
9969+ GR_AUDIT_CREATE | GR_AUDIT_DELETE)
9970+
9971+/* ACL subject-only mode flags */
9972+enum {
9973+ GR_KILL = 0x00000001,
9974+ GR_VIEW = 0x00000002,
9975+ GR_PROTECTED = 0x00000100,
9976+ GR_LEARN = 0x00000200,
9977+ GR_OVERRIDE = 0x00000400,
9978+ /* just a placeholder, this mode is only used in userspace */
9979+ GR_DUMMY = 0x00000800,
9980+
9981+ GR_PAXPAGE = 0x00001000,
9982+ GR_PAXSEGM = 0x00002000,
9983+ GR_PAXGCC = 0x00004000,
9984+ GR_PAXRANDMMAP = 0x00008000,
9985+ GR_PAXRANDEXEC = 0x00010000,
9986+ GR_PAXMPROTECT = 0x00020000,
9987+ GR_PROTSHM = 0x00040000,
9988+ GR_KILLPROC = 0x00080000,
9989+ GR_KILLIPPROC = 0x00100000,
9990+ /* just a placeholder, this mode is only used in userspace */
9991+ GR_NOTROJAN = 0x00200000,
9992+ GR_PROTPROCFD = 0x00400000,
9993+ GR_PROCACCT = 0x00800000
9994+};
9995+
9996+#define GR_CRASH_RES 11
9997+#define GR_UIDTABLE_MAX 500
9998+
9999+/* begin resource learning section */
10000+enum {
10001+ GR_RLIM_CPU_BUMP = 60,
10002+ GR_RLIM_FSIZE_BUMP = 50000,
10003+ GR_RLIM_DATA_BUMP = 10000,
10004+ GR_RLIM_STACK_BUMP = 1000,
10005+ GR_RLIM_CORE_BUMP = 10000,
10006+ GR_RLIM_RSS_BUMP = 500000,
10007+ GR_RLIM_NPROC_BUMP = 1,
10008+ GR_RLIM_NOFILE_BUMP = 5,
10009+ GR_RLIM_MEMLOCK_BUMP = 50000,
10010+ GR_RLIM_AS_BUMP = 500000,
10011+ GR_RLIM_LOCKS_BUMP = 2
10012+};
10013+
10014+#endif
10015diff -urN linux-2.4.22/include/linux/grinternal.h linux-2.4.22/include/linux/grinternal.h
10016--- linux-2.4.22/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
10017+++ linux-2.4.22/include/linux/grinternal.h 2003-09-02 19:47:41.000000000 -0400
10018@@ -0,0 +1,193 @@
10019+#ifndef __GRINTERNAL_H
10020+#define __GRINTERNAL_H
10021+
10022+#ifdef CONFIG_GRKERNSEC
10023+
10024+#include <linux/grdefs.h>
10025+#include <linux/grmsg.h>
10026+
10027+extern void gr_add_learn_entry(const char *fmt, ...);
10028+extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
10029+ const struct vfsmount *mnt);
10030+extern __u32 gr_check_create(const struct dentry *new_dentry,
10031+ const struct dentry *parent,
10032+ const struct vfsmount *mnt, const __u32 mode);
10033+extern int gr_check_protected_task(const struct task_struct *task);
10034+extern __inline__ __u32 to_gr_audit(const __u32 reqmode);
10035+extern int gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
10036+ struct dentry *old_dentry,
10037+ struct dentry *new_dentry,
10038+ struct vfsmount *mnt, const __u8 replace);
10039+extern int gr_set_acls(const int type);
10040+
10041+extern void gr_handle_alertkill(void);
10042+extern char *gr_to_filename(const struct dentry *dentry,
10043+ const struct vfsmount *mnt);
10044+extern char *gr_to_filename1(const struct dentry *dentry,
10045+ const struct vfsmount *mnt);
10046+extern char *gr_to_filename2(const struct dentry *dentry,
10047+ const struct vfsmount *mnt);
10048+extern char *gr_to_filename3(const struct dentry *dentry,
10049+ const struct vfsmount *mnt);
10050+
10051+extern int grsec_enable_link;
10052+extern int grsec_enable_fifo;
10053+extern int grsec_enable_execve;
10054+extern int grsec_enable_forkbomb;
10055+extern int grsec_forkbomb_gid;
10056+extern int grsec_forkbomb_sec;
10057+extern int grsec_forkbomb_max;
10058+extern int grsec_enable_execlog;
10059+extern int grsec_enable_signal;
10060+extern int grsec_enable_forkfail;
10061+extern int grsec_enable_time;
10062+extern int grsec_enable_chroot_shmat;
10063+extern int grsec_enable_chroot_findtask;
10064+extern int grsec_enable_chroot_mount;
10065+extern int grsec_enable_chroot_double;
10066+extern int grsec_enable_chroot_pivot;
10067+extern int grsec_enable_chroot_chdir;
10068+extern int grsec_enable_chroot_chmod;
10069+extern int grsec_enable_chroot_mknod;
10070+extern int grsec_enable_chroot_fchdir;
10071+extern int grsec_enable_chroot_nice;
10072+extern int grsec_enable_chroot_execlog;
10073+extern int grsec_enable_chroot_caps;
10074+extern int grsec_enable_chroot_sysctl;
10075+extern int grsec_enable_chroot_unix;
10076+extern int grsec_enable_tpe;
10077+extern int grsec_tpe_gid;
10078+extern int grsec_enable_tpe_all;
10079+extern int grsec_enable_sidcaps;
10080+extern int grsec_enable_randpid;
10081+extern int grsec_enable_socket_all;
10082+extern int grsec_socket_all_gid;
10083+extern int grsec_enable_socket_client;
10084+extern int grsec_socket_client_gid;
10085+extern int grsec_enable_socket_server;
10086+extern int grsec_socket_server_gid;
10087+extern int grsec_audit_gid;
10088+extern int grsec_enable_group;
10089+extern int grsec_enable_audit_ipc;
10090+extern int grsec_enable_mount;
10091+extern int grsec_enable_chdir;
10092+extern int grsec_lock;
10093+
10094+extern struct task_struct *child_reaper;
10095+
10096+extern spinlock_t grsec_alert_lock;
10097+extern unsigned long grsec_alert_wtime;
10098+extern unsigned long grsec_alert_fyet;
10099+
10100+extern spinlock_t grsec_alertgood_lock;
10101+extern unsigned long grsec_alertgood_wtime;
10102+extern unsigned long grsec_alertgood_fyet;
10103+
10104+extern spinlock_t grsec_audit_lock;
10105+
10106+#define gr_task_fullpath(tsk) (tsk->exec_file ? \
10107+ gr_to_filename2(tsk->exec_file->f_dentry, \
10108+ tsk->exec_file->f_vfsmnt) : "/")
10109+
10110+#define gr_parent_task_fullpath(tsk) (tsk->p_pptr->exec_file ? \
10111+ gr_to_filename3(tsk->p_pptr->exec_file->f_dentry, \
10112+ tsk->p_pptr->exec_file->f_vfsmnt) : "/")
10113+
10114+#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && \
10115+ ((tsk_a->fs->root->d_inode->i_dev != \
10116+ child_reaper->fs->root->d_inode->i_dev) || \
10117+ (tsk_a->fs->root->d_inode->i_ino != \
10118+ child_reaper->fs->root->d_inode->i_ino)))
10119+
10120+#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs->root->d_inode->i_dev == \
10121+ tsk_b->fs->root->d_inode->i_dev) && \
10122+ (tsk_a->fs->root->d_inode->i_ino == \
10123+ tsk_b->fs->root->d_inode->i_ino))
10124+
10125+#define DEFAULTSECARGS gr_task_fullpath(current), current->comm, \
10126+ current->pid, current->uid, \
10127+ current->euid, current->gid, current->egid, \
10128+ gr_parent_task_fullpath(current), \
10129+ current->p_pptr->comm, current->p_pptr->pid, \
10130+ current->p_pptr->uid, current->p_pptr->euid, \
10131+ current->p_pptr->gid, current->p_pptr->egid
10132+
10133+#define GR_CHROOT_CAPS ( \
10134+ CAP_TO_MASK(CAP_FOWNER) | \
10135+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
10136+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
10137+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
10138+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
10139+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
10140+ CAP_TO_MASK(CAP_IPC_OWNER))
10141+
10142+#define security_alert_good(normal_msg,args...) \
10143+({ \
10144+ spin_lock(&grsec_alertgood_lock); \
10145+ \
10146+ if (!grsec_alertgood_wtime || jiffies - grsec_alertgood_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
10147+ grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet = 0; \
10148+ if (current->curr_ip) \
10149+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
10150+ else \
10151+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
10152+ } else if((jiffies - grsec_alertgood_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alertgood_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
10153+ grsec_alertgood_fyet++; \
10154+ if (current->curr_ip) \
10155+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
10156+ else \
10157+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
10158+ } else if (grsec_alertgood_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
10159+ grsec_alertgood_wtime = jiffies; grsec_alertgood_fyet++; \
10160+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
10161+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
10162+ } \
10163+ \
10164+ spin_unlock(&grsec_alertgood_lock); \
10165+})
10166+
10167+#define security_alert(normal_msg,args...) \
10168+({ \
10169+ spin_lock(&grsec_alert_lock); \
10170+ \
10171+ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) { \
10172+ grsec_alert_wtime = jiffies; grsec_alert_fyet = 0; \
10173+ if (current->curr_ip) \
10174+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
10175+ else \
10176+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
10177+ } else if((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) { \
10178+ grsec_alert_fyet++; \
10179+ if (current->curr_ip) \
10180+ printk(KERN_ALERT "grsec: From %u.%u.%u.%u: " normal_msg "\n", NIPQUAD(current->curr_ip) , ## args); \
10181+ else \
10182+ printk(KERN_ALERT "grsec: " normal_msg "\n" , ## args); \
10183+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) { \
10184+ grsec_alert_wtime = jiffies; grsec_alert_fyet++; \
10185+ printk(KERN_ALERT "grsec: more alerts, logging disabled for " \
10186+ "%d seconds\n", CONFIG_GRKERNSEC_FLOODTIME); \
10187+ } \
10188+ \
10189+ gr_handle_alertkill(); \
10190+ spin_unlock(&grsec_alert_lock); \
10191+})
10192+
10193+#define security_audit(normal_msg,args...) \
10194+({ \
10195+ spin_lock(&grsec_audit_lock); \
10196+ if (current->curr_ip) \
10197+ printk(KERN_INFO "grsec: From %u.%u.%u.%u: " normal_msg "\n", \
10198+ NIPQUAD(current->curr_ip) , ## args); \
10199+ else \
10200+ printk(KERN_INFO "grsec: " normal_msg "\n", ## args); \
10201+ spin_unlock(&grsec_audit_lock); \
10202+})
10203+
10204+#define security_learn(normal_msg,args...) \
10205+({ \
10206+ gr_add_learn_entry(normal_msg "\n", ## args); \
10207+})
10208+
10209+#endif
10210+
10211+#endif
10212diff -urN linux-2.4.22/include/linux/grmsg.h linux-2.4.22/include/linux/grmsg.h
10213--- linux-2.4.22/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
10214+++ linux-2.4.22/include/linux/grmsg.h 2003-09-02 19:47:26.000000000 -0400
10215@@ -0,0 +1,104 @@
10216+#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"
10217+#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"
10218+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by " DEFAULTSECMSG
10219+#define GR_IOPERM_MSG "denied use of ioperm() by " DEFAULTSECMSG
10220+#define GR_IOPL_MSG "denied use of iopl() by " DEFAULTSECMSG
10221+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by " DEFAULTSECMSG
10222+#define GR_UNIX_CHROOT_MSG "denied connect to abstract AF_UNIX socket outside of chroot by " DEFAULTSECMSG
10223+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by " DEFAULTSECMSG
10224+#define GR_KMEM_MSG "attempted write to /dev/kmem by " DEFAULTSECMSG
10225+#define GR_PORT_OPEN_MSG "attempted open of /dev/port by " DEFAULTSECMSG
10226+#define GR_MEM_WRITE_MSG "attempted write of /dev/mem by " DEFAULTSECMSG
10227+#define GR_MEM_MMAP_MSG "attempted mmap write of /dev/[k]mem by " DEFAULTSECMSG
10228+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by " DEFAULTSECMSG
10229+#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"
10230+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by " DEFAULTSECMSG
10231+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by " DEFAULTSECMSG
10232+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by " DEFAULTSECMSG
10233+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by " DEFAULTSECMSG
10234+#define GR_MKNOD_CHROOT_MSG "refused attempt to mknod %.950s from chroot by " DEFAULTSECMSG
10235+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by " DEFAULTSECMSG
10236+#define GR_UNIXCONNECT_ACL_MSG "%s connect to the unix domain socket %.950s by " DEFAULTSECMSG
10237+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by " DEFAULTSECMSG
10238+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by " DEFAULTSECMSG
10239+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by " DEFAULTSECMSG
10240+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by " DEFAULTSECMSG
10241+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for " DEFAULTSECMSG
10242+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by " DEFAULTSECMSG
10243+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by " DEFAULTSECMSG
10244+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by " DEFAULTSECMSG
10245+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by " DEFAULTSECMSG
10246+#define GR_NPROC_MSG "attempt to overstep process limit by " DEFAULTSECMSG
10247+#define GR_EXEC_ACL_MSG "%s execution of %.950s by " DEFAULTSECMSG
10248+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by " DEFAULTSECMSG
10249+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning uid %u from login for %lu seconds"
10250+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " Banning execution of [%.16s:%lu] for %lu seconds"
10251+#define GR_MOUNT_CHROOT_MSG "denied attempt to mount %.30s as %.930s from chroot by " DEFAULTSECMSG
10252+#define GR_PIVOT_CHROOT_MSG "denied attempt to pivot_root from chroot by " DEFAULTSECMSG
10253+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by " DEFAULTSECMSG
10254+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by " DEFAULTSECMSG
10255+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by " DEFAULTSECMSG
10256+#define GR_CHROOT_CHROOT_MSG "denied attempt to double chroot to %.950s by " DEFAULTSECMSG
10257+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by " DEFAULTSECMSG
10258+#define GR_CHMOD_CHROOT_MSG "denied attempt to chmod +s %.950s by " DEFAULTSECMSG
10259+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by " DEFAULTSECMSG
10260+#define GR_CHROOT_FCHDIR_MSG "attempted fchdir outside of chroot to %.950s by " DEFAULTSECMSG
10261+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by " DEFAULTSECMSG
10262+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by " DEFAULTSECMSG
10263+#define GR_INITF_ACL_MSG "init_variables() failed %s"
10264+#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"
10265+#define GR_DEV_ACL_MSG "/dev/grsec: being fed garbage %d bytes sent %d required"
10266+#define GR_SHUTS_ACL_MSG "shutdown auth success for " DEFAULTSECMSG
10267+#define GR_SHUTF_ACL_MSG "shutdown auth failure for " DEFAULTSECMSG
10268+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for " DEFAULTSECMSG
10269+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for " DEFAULTSECMSG
10270+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for " DEFAULTSECMSG
10271+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for " DEFAULTSECMSG
10272+#define GR_ENABLE_ACL_MSG "Loaded %s"
10273+#define GR_ENABLEF_ACL_MSG "Unable to load %s for " DEFAULTSECMSG " RBAC system may already be enabled."
10274+#define GR_RELOADI_ACL_MSG "Ignoring reload request for disabled RBAC system"
10275+#define GR_RELOAD_ACL_MSG "Reloaded %s"
10276+#define GR_RELOADF_ACL_MSG "Failed reload of %s for " DEFAULTSECMSG
10277+#define GR_SPROLEI_ACL_MSG "Ignoring change to special role for disabled RBAC system for " DEFAULTSECMSG
10278+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by " DEFAULTSECMSG
10279+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by " DEFAULTSECMSG
10280+#define GR_SPROLEF_ACL_MSG "special role %s failure for " DEFAULTSECMSG
10281+#define GR_UNSPROLEI_ACL_MSG "Ignoring unauth of special role for disabled RBAC system for " DEFAULTSECMSG
10282+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by " DEFAULTSECMSG
10283+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for " DEFAULTSECMSG
10284+#define GR_INVMODE_ACL_MSG "Invalid mode %d by " DEFAULTSECMSG
10285+#define GR_MAXPW_ACL_MSG "Maximum pw attempts reached (%d), locking password authentication"
10286+#define GR_MAXROLEPW_ACL_MSG "Maximum pw attempts reached (%d) trying to auth to special role %s, locking auth for role of " DEFAULTSECMSG
10287+#define GR_PRIORITY_CHROOT_MSG "attempted priority change of process (%.16s:%d) by " DEFAULTSECMSG
10288+#define GR_CAPSET_CHROOT_MSG "denied capset of (%.16s:%d) within chroot by " DEFAULTSECMSG
10289+#define GR_FAILFORK_MSG "failed fork with errno %d by " DEFAULTSECMSG
10290+#define GR_NICE_CHROOT_MSG "attempted priority change by " DEFAULTSECMSG
10291+#define GR_UNISIGLOG_MSG "signal %d sent to " DEFAULTSECMSG
10292+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by " DEFAULTSECMSG
10293+#define GR_SIG_ACL_MSG "Attempted send of signal %d to protected task " DEFAULTSECMSG " by " DEFAULTSECMSG
10294+#define GR_SYSCTL_MSG "attempt to modify grsecurity sysctl value : %.32s by " DEFAULTSECMSG
10295+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by " DEFAULTSECMSG
10296+#define GR_TIME_MSG "time set by " DEFAULTSECMSG
10297+#define GR_DEFACL_MSG "Fatal: Unable to find ACL for (%.16s:%d)"
10298+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by " DEFAULTSECMSG
10299+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by " DEFAULTSECMSG
10300+#define GR_SOCK_MSG "attempted socket(%.16s,%.16s,%.16s) by " DEFAULTSECMSG
10301+#define GR_BIND_MSG "attempted bind() by " DEFAULTSECMSG
10302+#define GR_CONNECT_MSG "attempted connect by " DEFAULTSECMSG
10303+#define GR_BIND_ACL_MSG "attempted bind to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
10304+#define GR_CONNECT_ACL_MSG "attempted connect to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by " DEFAULTSECMSG
10305+#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"
10306+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process " DEFAULTSECMSG
10307+#define GR_CAP_ACL_MSG "use of %s denied for " DEFAULTSECMSG
10308+#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by " DEFAULTSECMSG
10309+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by " DEFAULTSECMSG
10310+#define GR_MOUNT_AUDIT_MSG "mount %.30s to %.64s by " DEFAULTSECMSG
10311+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by " DEFAULTSECMSG
10312+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.63s) by " DEFAULTSECMSG
10313+#define GR_MSGQ_AUDIT_MSG "message queue created by " DEFAULTSECMSG
10314+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%d euid:%d removed by " DEFAULTSECMSG
10315+#define GR_SEM_AUDIT_MSG "semaphore created by " DEFAULTSECMSG
10316+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%d euid:%d removed by " DEFAULTSECMSG
10317+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by " DEFAULTSECMSG
10318+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%d euid:%d removed by " DEFAULTSECMSG
10319+#define GR_RESOURCE_MSG "attempted resource overstep by requesting %lu for %.16s against limit %lu by " DEFAULTSECMSG
10320diff -urN linux-2.4.22/include/linux/grsecurity.h linux-2.4.22/include/linux/grsecurity.h
10321--- linux-2.4.22/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
10322+++ linux-2.4.22/include/linux/grsecurity.h 2003-09-02 19:33:29.000000000 -0400
10323@@ -0,0 +1,173 @@
10324+#ifndef GR_SECURITY_H
10325+#define GR_SECURITY_H
10326+
10327+extern int gr_pid_is_chrooted(const struct task_struct *p);
10328+extern int gr_handle_chroot_nice(void);
10329+extern int gr_handle_chroot_sysctl(const int op);
10330+extern int gr_handle_chroot_capset(const struct task_struct *target);
10331+extern int gr_handle_chroot_setpriority(const struct task_struct *p,
10332+ const int niceval);
10333+extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
10334+extern int gr_handle_chroot_chroot(const struct dentry *dentry,
10335+ const struct vfsmount *mnt);
10336+extern void gr_handle_chroot_caps(struct task_struct *task);
10337+extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
10338+extern int gr_handle_chroot_chmod(const struct dentry *dentry,
10339+ const struct vfsmount *mnt, const int mode);
10340+extern int gr_handle_chroot_mknod(const struct dentry *dentry,
10341+ const struct vfsmount *mnt, const int mode);
10342+extern int gr_handle_chroot_mount(const struct dentry *dentry,
10343+ const struct vfsmount *mnt,
10344+ const char *dev_name);
10345+extern int gr_handle_chroot_pivot(void);
10346+extern int gr_handle_chroot_unix(const pid_t pid);
10347+
10348+extern int gr_handle_rawio(const struct inode *inode);
10349+extern int gr_handle_nproc(void);
10350+
10351+extern void gr_handle_ioperm(void);
10352+extern void gr_handle_iopl(void);
10353+
10354+extern int gr_tpe_allow(const struct file *file);
10355+
10356+extern int gr_random_pid(spinlock_t * pid_lock);
10357+
10358+extern void gr_log_forkfail(const int retval);
10359+extern void gr_log_timechange(void);
10360+extern void gr_log_signal(const int sig, const struct task_struct *t);
10361+extern void gr_log_chdir(const struct dentry *dentry,
10362+ const struct vfsmount *mnt);
10363+extern void gr_log_chroot_exec(const struct dentry *dentry,
10364+ const struct vfsmount *mnt);
10365+extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
10366+extern void gr_log_remount(const char *devname, const int retval);
10367+extern void gr_log_unmount(const char *devname, const int retval);
10368+extern void gr_log_mount(const char *from, const char *to, const int retval);
10369+extern void gr_log_msgget(const int ret, const int msgflg);
10370+extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
10371+extern void gr_log_semget(const int err, const int semflg);
10372+extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
10373+extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
10374+extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
10375+
10376+extern int gr_handle_follow_link(const struct inode *parent,
10377+ const struct inode *inode,
10378+ const struct dentry *dentry,
10379+ const struct vfsmount *mnt);
10380+extern int gr_handle_fifo(const struct dentry *dentry,
10381+ const struct vfsmount *mnt,
10382+ const struct dentry *dir, const int flag,
10383+ const int acc_mode);
10384+extern int gr_handle_hardlink(const struct dentry *dentry,
10385+ const struct vfsmount *mnt,
10386+ struct inode *inode,
10387+ const int mode, const char *to);
10388+
10389+extern int gr_is_capable(const int cap);
10390+extern void gr_learn_resource(const struct task_struct *task, const int limit,
10391+ const unsigned long wanted);
10392+extern void gr_copy_label(struct task_struct *tsk);
10393+extern void gr_handle_crash(struct task_struct *task, const int sig);
10394+extern int gr_handle_signal(const struct task_struct *p, const int sig);
10395+extern int gr_check_crash_uid(const uid_t uid);
10396+extern int gr_check_protected_task(const struct task_struct *task);
10397+extern int gr_acl_handle_mmap(const struct file *file,
10398+ const unsigned long prot);
10399+extern int gr_acl_handle_mprotect(const struct file *file,
10400+ const unsigned long prot);
10401+extern int gr_check_hidden_task(const struct task_struct *tsk);
10402+extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
10403+ const struct vfsmount *mnt);
10404+extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
10405+ const struct vfsmount *mnt);
10406+extern __u32 gr_acl_handle_access(const struct dentry *dentry,
10407+ const struct vfsmount *mnt, const int fmode);
10408+extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
10409+ const struct vfsmount *mnt, mode_t mode);
10410+extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
10411+ const struct vfsmount *mnt, mode_t mode);
10412+extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
10413+ const struct vfsmount *mnt);
10414+extern int gr_handle_ptrace_exec(const struct dentry *dentry,
10415+ const struct vfsmount *mnt);
10416+extern int gr_handle_ptrace(struct task_struct *task, const long request);
10417+extern int gr_handle_mmap(const struct file *filp, const unsigned long prot);
10418+extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
10419+ const struct vfsmount *mnt);
10420+extern int gr_check_crash_exec(const struct file *filp);
10421+extern int gr_acl_is_enabled(void);
10422+extern void gr_set_kernel_label(struct task_struct *task);
10423+extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
10424+ const gid_t gid);
10425+extern void gr_set_proc_label(const struct dentry *dentry,
10426+ const struct vfsmount *mnt);
10427+extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
10428+ const struct vfsmount *mnt);
10429+extern __u32 gr_acl_handle_open(const struct dentry *dentry,
10430+ const struct vfsmount *mnt, const int fmode);
10431+extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
10432+ const struct dentry *p_dentry,
10433+ const struct vfsmount *p_mnt, const int fmode,
10434+ const int imode);
10435+extern void gr_handle_create(const struct dentry *dentry,
10436+ const struct vfsmount *mnt);
10437+extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
10438+ const struct dentry *parent_dentry,
10439+ const struct vfsmount *parent_mnt,
10440+ const int mode);
10441+extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
10442+ const struct dentry *parent_dentry,
10443+ const struct vfsmount *parent_mnt);
10444+extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
10445+ const struct vfsmount *mnt);
10446+extern void gr_handle_delete(const ino_t ino, const kdev_t dev);
10447+extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
10448+ const struct vfsmount *mnt);
10449+extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
10450+ const struct dentry *parent_dentry,
10451+ const struct vfsmount *parent_mnt,
10452+ const char *from);
10453+extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
10454+ const struct dentry *parent_dentry,
10455+ const struct vfsmount *parent_mnt,
10456+ const struct dentry *old_dentry,
10457+ const struct vfsmount *old_mnt, const char *to);
10458+extern int gr_acl_handle_rename(struct dentry *new_dentry,
10459+ struct dentry *parent_dentry,
10460+ const struct vfsmount *parent_mnt,
10461+ struct dentry *old_dentry,
10462+ struct inode *old_parent_inode,
10463+ struct vfsmount *old_mnt, const char *newname);
10464+extern __u32 gr_check_link(const struct dentry *new_dentry,
10465+ const struct dentry *parent_dentry,
10466+ const struct vfsmount *parent_mnt,
10467+ const struct dentry *old_dentry,
10468+ const struct vfsmount *old_mnt);
10469+extern __u32 gr_acl_handle_filldir(const struct dentry *dentry,
10470+ const struct vfsmount *mnt, const ino_t ino);
10471+extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
10472+ const struct vfsmount *mnt);
10473+extern void gr_acl_handle_exit(void);
10474+extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
10475+extern int gr_acl_handle_procpidmem(const struct task_struct *task);
10476+extern __u32 gr_cap_rtnetlink(void);
10477+
10478+#ifdef CONFIG_GRKERNSEC
10479+extern void gr_handle_mem_write(void);
10480+extern void gr_handle_kmem_write(void);
10481+extern void gr_handle_open_port(void);
10482+extern int gr_handle_mem_mmap(const unsigned long offset,
10483+ struct vm_area_struct *vma);
10484+
10485+extern __u16 ip_randomid(void);
10486+extern __u32 ip_randomisn(void);
10487+extern unsigned long get_random_long(void);
10488+
10489+extern int grsec_enable_dmesg;
10490+extern int grsec_enable_randid;
10491+extern int grsec_enable_randisn;
10492+extern int grsec_enable_randsrc;
10493+extern int grsec_enable_randrpc;
10494+#endif
10495+
10496+#endif
10497diff -urN linux-2.4.22/include/linux/mm.h linux-2.4.22/include/linux/mm.h
10498--- linux-2.4.22/include/linux/mm.h 2003-09-01 22:19:02.000000000 -0400
10499+++ linux-2.4.22/include/linux/mm.h 2003-09-02 19:33:29.000000000 -0400
10500@@ -22,9 +22,13 @@
10501 extern struct list_head active_list;
10502 extern struct list_head inactive_list;
10503
10504+extern void gr_learn_resource(const struct task_struct * task, const int limit,
10505+ const unsigned long wanted);
10506+
10507 #include <asm/page.h>
10508 #include <asm/pgtable.h>
10509 #include <asm/atomic.h>
10510+#include <asm/mman.h>
10511
10512 /*
10513 * Linux kernel virtual memory manager primitives.
10514@@ -649,6 +719,11 @@
10515 address &= PAGE_MASK;
10516 spin_lock(&vma->vm_mm->page_table_lock);
10517 grow = (vma->vm_start - address) >> PAGE_SHIFT;
10518+
10519+ gr_learn_resource(current, RLIMIT_STACK, vma->vm_end - address);
10520+ gr_learn_resource(current, RLIMIT_AS, (vma->vm_mm->total_vm + grow) << PAGE_SHIFT);
10521+ gr_learn_resource(current, RLIMIT_MEMLOCK, (vma->vm_mm->locked_vm + grow) << PAGE_SHIFT);
10522+
10523 if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
10524 ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
10525 spin_unlock(&vma->vm_mm->page_table_lock);
10526diff -urN linux-2.4.22/include/linux/proc_fs.h linux-2.4.22/include/linux/proc_fs.h
10527--- linux-2.4.22/include/linux/proc_fs.h 2003-09-01 22:19:02.000000000 -0400
10528+++ linux-2.4.22/include/linux/proc_fs.h 2003-09-02 19:33:36.000000000 -0400
10529@@ -143,6 +143,9 @@
10530 extern struct proc_dir_entry *proc_mknod(const char *,mode_t,
10531 struct proc_dir_entry *,kdev_t);
10532 extern struct proc_dir_entry *proc_mkdir(const char *,struct proc_dir_entry *);
10533+#ifdef CONFIG_GRKERNSEC_PROC
10534+extern struct proc_dir_entry *proc_priv_mkdir(const char *, struct proc_dir_entry *);
10535+#endif
10536
10537 static inline struct proc_dir_entry *create_proc_read_entry(const char *name,
10538 mode_t mode, struct proc_dir_entry *base,
10539diff -urN linux-2.4.22/include/linux/sched.h linux-2.4.22/include/linux/sched.h
10540--- linux-2.4.22/include/linux/sched.h 2003-09-01 22:19:02.000000000 -0400
10541+++ linux-2.4.22/include/linux/sched.h 2003-09-02 19:33:29.000000000 -0400
10542@@ -27,6 +27,9 @@
10543 #include <linux/securebits.h>
10544 #include <linux/fs_struct.h>
10545
10546+extern int gr_is_capable(const int cap);
10547+extern int gr_pid_is_chrooted(const struct task_struct *p);
10548+
10549 struct exec_domain;
10550
10551 /*
10552@@ -415,6 +432,19 @@
10553
10554 /* journalling filesystem info */
10555 void *journal_info;
10556+
10557+#ifdef CONFIG_GRKERNSEC
10558+/* added by grsecurity's ACL system */
10559+ struct acl_subject_label *acl;
10560+ struct acl_role_label *role;
10561+ struct file *exec_file;
10562+ u32 curr_ip;
10563+ u16 acl_role_id;
10564+ u8 acl_sp_role:1;
10565+ u8 used_accept:1;
10566+ u8 used_connect:1;
10567+ u8 is_writable:1;
10568+#endif
10569 };
10570
10571 /*
10572@@ -549,6 +586,8 @@
10573 *p->pidhash_pprev = p->pidhash_next;
10574 }
10575
10576+#include <asm/current.h>
10577+
10578 static inline task_t *find_task_by_pid(int pid)
10579 {
10580 task_t *p, **htable = &pidhash[pid_hashfn(pid)];
10581@@ -556,6 +595,8 @@
10582 for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
10583 ;
10584
10585+ if(gr_pid_is_chrooted(p)) p = NULL;
10586+
10587 return p;
10588 }
10589
10590@@ -576,8 +617,6 @@
10591 extern struct user_struct * alloc_uid(uid_t);
10592 extern void free_uid(struct user_struct *);
10593
10594-#include <asm/current.h>
10595-
10596 extern unsigned long volatile jiffies;
10597 extern unsigned long itimer_ticks;
10598 extern unsigned long itimer_next;
10599@@ -741,7 +780,7 @@
10600 static inline int capable(int cap)
10601 {
10602 #if 1 /* ok now */
10603- if (cap_raised(current->cap_effective, cap))
10604+ if (cap_raised(current->cap_effective, cap) && gr_is_capable(cap))
10605 #else
10606 if (cap_is_fs_cap(cap) ? current->fsuid == 0 : current->euid == 0)
10607 #endif
10608diff -urN linux-2.4.22/include/linux/sysctl.h linux-2.4.22/include/linux/sysctl.h
10609--- linux-2.4.22/include/linux/sysctl.h 2003-09-01 22:19:02.000000000 -0400
10610+++ linux-2.4.22/include/linux/sysctl.h 2003-09-02 19:33:31.000000000 -0400
10611@@ -127,6 +127,7 @@
10612 KERN_CORE_PATTERN=56, /* string: pattern for core-files */
10613 KERN_PPC_L3CR=57, /* l3cr register on PPC */
10614 KERN_EXCEPTION_TRACE=58, /* boolean: exception trace */
10615+ KERN_GRSECURITY=68, /* grsecurity */
10616 };
10617
10618
10619diff -urN linux-2.4.22/include/net/inetpeer.h linux-2.4.22/include/net/inetpeer.h
10620--- linux-2.4.22/include/net/inetpeer.h 2003-09-01 22:19:06.000000000 -0400
10621+++ linux-2.4.22/include/net/inetpeer.h 2003-09-02 19:37:15.000000000 -0400
10622@@ -13,6 +13,7 @@
10623 #include <linux/init.h>
10624 #include <linux/sched.h>
10625 #include <linux/spinlock.h>
10626+
10627 #include <asm/atomic.h>
10628
10629 struct inet_peer
10630@@ -34,6 +35,11 @@
10631 /* can be called with or without local BH being disabled */
10632 struct inet_peer *inet_getpeer(__u32 daddr, int create);
10633
10634+#ifdef CONFIG_GRKERNSEC_RANDID
10635+extern int grsec_enable_randid;
10636+extern __u16 ip_randomid(void);
10637+#endif
10638+
10639 extern spinlock_t inet_peer_unused_lock;
10640 extern struct inet_peer *inet_peer_unused_head;
10641 extern struct inet_peer **inet_peer_unused_tailp;
10642@@ -58,7 +64,14 @@
10643 __u16 id;
10644
10645 spin_lock_bh(&inet_peer_idlock);
10646- id = p->ip_id_count++;
10647+
10648+#ifdef CONFIG_GRKERNSEC_RANDID
10649+ if(grsec_enable_randid)
10650+ id = htons(ip_randomid());
10651+ else
10652+#endif
10653+ id = p->ip_id_count++;
10654+
10655 spin_unlock_bh(&inet_peer_idlock);
10656 return id;
10657 }
10658diff -urN linux-2.4.22/include/net/ip.h linux-2.4.22/include/net/ip.h
10659--- linux-2.4.22/include/net/ip.h 2003-09-01 22:19:03.000000000 -0400
10660+++ linux-2.4.22/include/net/ip.h 2003-09-02 19:37:15.000000000 -0400
10661@@ -64,6 +64,11 @@
10662 void (*destructor)(struct sock *);
10663 };
10664
10665+#ifdef CONFIG_GRKERNSEC_RANDID
10666+extern int grsec_enable_randid;
10667+extern __u16 ip_randomid(void);
10668+#endif
10669+
10670 extern struct ip_ra_chain *ip_ra_chain;
10671 extern rwlock_t ip_ra_lock;
10672
10673@@ -197,7 +202,13 @@
10674 * does not change, they drop every other packet in
10675 * a TCP stream using header compression.
10676 */
10677- iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
10678+
10679+#ifdef CONFIG_GRKERNSEC_RANDID
10680+ if(grsec_enable_randid)
10681+ iph->id = htons(ip_randomid());
10682+ else
10683+#endif
10684+ iph->id = ((sk && sk->daddr) ? htons(sk->protinfo.af_inet.id++) : 0);
10685 } else
10686 __ip_select_ident(iph, dst);
10687 }
10688diff -urN linux-2.4.22/init/main.c linux-2.4.22/init/main.c
10689--- linux-2.4.22/init/main.c 2003-09-01 22:19:01.000000000 -0400
10690+++ linux-2.4.22/init/main.c 2003-09-02 19:29:42.000000000 -0400
10691@@ -27,6 +27,7 @@
10692 #include <linux/iobuf.h>
10693 #include <linux/bootmem.h>
10694 #include <linux/tty.h>
10695+#include <linux/grsecurity.h>
10696
10697 #include <asm/io.h>
10698 #include <asm/bugs.h>
10699@@ -111,6 +112,8 @@
10700 extern void ipc_init(void);
10701 #endif
10702
10703+extern void grsecurity_init(void);
10704+
10705 /*
10706 * Boot command-line arguments
10707 */
10708@@ -552,6 +555,7 @@
10709 do_basic_setup();
10710
10711 prepare_namespace();
10712+ grsecurity_init();
10713
10714 /*
10715 * Ok, we have completed the initial bootup, and
10716diff -urN linux-2.4.22/ipc/msg.c linux-2.4.22/ipc/msg.c
10717--- linux-2.4.22/ipc/msg.c 2003-09-01 22:19:11.000000000 -0400
10718+++ linux-2.4.22/ipc/msg.c 2003-09-02 19:29:42.000000000 -0400
10719@@ -22,6 +22,7 @@
10720 #include <linux/init.h>
10721 #include <linux/proc_fs.h>
10722 #include <linux/list.h>
10723+#include <linux/grsecurity.h>
10724 #include <asm/uaccess.h>
10725 #include "util.h"
10726
10727@@ -326,6 +327,9 @@
10728 msg_unlock(id);
10729 }
10730 up(&msg_ids.sem);
10731+
10732+ gr_log_msgget(ret, msgflg);
10733+
10734 return ret;
10735 }
10736
10737@@ -560,6 +564,8 @@
10738 break;
10739 }
10740 case IPC_RMID:
10741+ gr_log_msgrm(ipcp->uid, ipcp->cuid);
10742+
10743 freeque (msqid);
10744 break;
10745 }
10746diff -urN linux-2.4.22/ipc/sem.c linux-2.4.22/ipc/sem.c
10747--- linux-2.4.22/ipc/sem.c 2003-09-01 22:19:11.000000000 -0400
10748+++ linux-2.4.22/ipc/sem.c 2003-09-02 19:29:42.000000000 -0400
10749@@ -63,6 +63,7 @@
10750 #include <linux/init.h>
10751 #include <linux/proc_fs.h>
10752 #include <linux/time.h>
10753+#include <linux/grsecurity.h>
10754 #include <asm/uaccess.h>
10755 #include "util.h"
10756
10757@@ -182,6 +183,9 @@
10758 }
10759
10760 up(&sem_ids.sem);
10761+
10762+ gr_log_semget(err, semflg);
10763+
10764 return err;
10765 }
10766
10767@@ -724,6 +728,8 @@
10768
10769 switch(cmd){
10770 case IPC_RMID:
10771+ gr_log_semrm(ipcp->uid, ipcp->cuid);
10772+
10773 freeary(semid);
10774 err = 0;
10775 break;
10776diff -urN linux-2.4.22/ipc/shm.c linux-2.4.22/ipc/shm.c
10777--- linux-2.4.22/ipc/shm.c 2003-09-01 22:19:11.000000000 -0400
10778+++ linux-2.4.22/ipc/shm.c 2003-09-02 19:29:42.000000000 -0400
10779@@ -23,6 +23,7 @@
10780 #include <linux/mman.h>
10781 #include <linux/proc_fs.h>
10782 #include <asm/uaccess.h>
10783+#include <linux/grsecurity.h>
10784
10785 #include "util.h"
10786
10787@@ -38,8 +39,21 @@
10788 time_t shm_ctim;
10789 pid_t shm_cprid;
10790 pid_t shm_lprid;
10791+
10792+#ifdef CONFIG_GRKERNSEC
10793+ time_t shm_createtime;
10794+ pid_t shm_lapid;
10795+#endif
10796 };
10797
10798+#ifdef CONFIG_GRKERNSEC
10799+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
10800+ const time_t shm_createtime, const uid_t cuid,
10801+ const int shmid);
10802+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
10803+ const time_t shm_createtime);
10804+#endif
10805+
10806 #define shm_flags shm_perm.mode
10807
10808 static struct file_operations shm_file_operations;
10809@@ -209,6 +223,9 @@
10810 shp->shm_lprid = 0;
10811 shp->shm_atim = shp->shm_dtim = 0;
10812 shp->shm_ctim = CURRENT_TIME;
10813+#ifdef CONFIG_GRKERNSEC
10814+ shp->shm_createtime = CURRENT_TIME;
10815+#endif
10816 shp->shm_segsz = size;
10817 shp->shm_nattch = 0;
10818 shp->id = shm_buildid(id,shp->shm_perm.seq);
10819@@ -254,6 +271,9 @@
10820 shm_unlock(id);
10821 }
10822 up(&shm_ids.sem);
10823+
10824+ gr_log_shmget(err, shmflg, size);
10825+
10826 return err;
10827 }
10828
10829@@ -509,6 +529,9 @@
10830 err=-EPERM;
10831 goto out_unlock_up;
10832 }
10833+
10834+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
10835+
10836 if (shp->shm_nattch){
10837 shp->shm_flags |= SHM_DEST;
10838 /* Do not find it any more */
10839@@ -622,9 +645,28 @@
10840 shm_unlock(shmid);
10841 return -EACCES;
10842 }
10843+
10844+#ifdef CONFIG_GRKERNSEC
10845+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
10846+ shp->shm_perm.cuid, shmid)) {
10847+ shm_unlock(shmid);
10848+ return -EACCES;
10849+ }
10850+
10851+ if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
10852+ shm_unlock(shmid);
10853+ return -EACCES;
10854+ }
10855+#endif
10856+
10857 file = shp->shm_file;
10858 size = file->f_dentry->d_inode->i_size;
10859 shp->shm_nattch++;
10860+
10861+#ifdef CONFIG_GRKERNSEC
10862+ shp->shm_lapid = current->pid;
10863+#endif
10864+
10865 shm_unlock(shmid);
10866
10867 down_write(&current->mm->mmap_sem);
10868diff -urN linux-2.4.22/kernel/capability.c linux-2.4.22/kernel/capability.c
10869--- linux-2.4.22/kernel/capability.c 2003-09-01 22:19:01.000000000 -0400
10870+++ linux-2.4.22/kernel/capability.c 2003-09-02 19:29:42.000000000 -0400
10871@@ -7,6 +7,7 @@
10872
10873 #include <linux/mm.h>
10874 #include <asm/uaccess.h>
10875+#include <linux/grsecurity.h>
10876
10877 kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
10878
10879@@ -168,6 +169,10 @@
10880 target = current;
10881 }
10882
10883+ if (gr_handle_chroot_capset(target)) {
10884+ error = -ESRCH;
10885+ goto out;
10886+ }
10887
10888 /* verify restrictions on target's new Inheritable set */
10889 if (!cap_issubset(inheritable,
10890diff -urN linux-2.4.22/kernel/exit.c linux-2.4.22/kernel/exit.c
10891--- linux-2.4.22/kernel/exit.c 2003-09-01 22:19:01.000000000 -0400
10892+++ linux-2.4.22/kernel/exit.c 2003-09-02 19:29:42.000000000 -0400
10893@@ -16,6 +16,7 @@
10894 #ifdef CONFIG_BSD_PROCESS_ACCT
10895 #include <linux/acct.h>
10896 #endif
10897+#include <linux/grsecurity.h>
10898
10899 #include <asm/uaccess.h>
10900 #include <asm/pgtable.h>
10901@@ -165,12 +165,21 @@
10902
10903 write_lock_irq(&tasklist_lock);
10904
10905+#ifdef CONFIG_GRKERNSEC
10906+ if (current->exec_file) {
10907+ fput(current->exec_file);
10908+ current->exec_file = NULL;
10909+ }
10910+#endif
10911+
10912 /* Reparent to init */
10913 REMOVE_LINKS(current);
10914 current->p_pptr = child_reaper;
10915 current->p_opptr = child_reaper;
10916 SET_LINKS(current);
10917
cee78712 10918+ gr_set_kernel_label(current);
ada7ca3f
JR
10919+
10920 /* Set the exit signal to SIGCHLD so we signal init on exit */
10921 current->exit_signal = SIGCHLD;
10922
10923@@ -439,6 +440,10 @@
10924 #ifdef CONFIG_BSD_PROCESS_ACCT
10925 acct_process(code);
10926 #endif
10927+
10928+ gr_acl_handle_psacct(tsk, code);
10929+ gr_acl_handle_exit();
10930+
10931 __exit_mm(tsk);
10932
10933 lock_kernel();
10934diff -urN linux-2.4.22/kernel/fork.c linux-2.4.22/kernel/fork.c
10935--- linux-2.4.22/kernel/fork.c 2003-09-01 22:19:01.000000000 -0400
10936+++ linux-2.4.22/kernel/fork.c 2003-09-02 19:29:42.000000000 -0400
10937@@ -22,6 +22,7 @@
10938 #include <linux/namespace.h>
10939 #include <linux/personality.h>
10940 #include <linux/compiler.h>
10941+#include <linux/grsecurity.h>
10942
10943 #include <asm/pgtable.h>
10944 #include <asm/pgalloc.h>
10945@@ -93,6 +94,10 @@
10946 if (flags & CLONE_PID)
10947 return current->pid;
10948
10949+ pid = gr_random_pid(&lastpid_lock);
10950+ if (pid)
10951+ return pid;
10952+
10953 spin_lock(&lastpid_lock);
10954 beginpid = last_pid;
10955 if((++last_pid) & 0xffff8000) {
10956@@ -667,6 +672,9 @@
10957 * friends to set the per-user process limit to something lower
10958 * than the amount of processes root is running. -- Rik
10959 */
10960+
10961+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes));
10962+
10963 if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur
10964 && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE))
10965 goto bad_fork_free;
10966@@ -751,6 +759,7 @@
10967 retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
10968 if (retval)
10969 goto bad_fork_cleanup_namespace;
10970+ gr_copy_label(p);
10971 p->semundo = NULL;
10972
10973 /* Our parent execution domain becomes current domain
10974@@ -836,6 +845,9 @@
10975 free_uid(p->user);
10976 bad_fork_free:
10977 free_task_struct(p);
10978+
10979+ gr_log_forkfail(retval);
10980+
10981 goto fork_out;
10982 }
10983
10984diff -urN linux-2.4.22/kernel/ksyms.c linux-2.4.22/kernel/ksyms.c
10985--- linux-2.4.22/kernel/ksyms.c 2003-09-01 22:19:01.000000000 -0400
10986+++ linux-2.4.22/kernel/ksyms.c 2003-09-02 19:29:42.000000000 -0400
10987@@ -49,6 +49,7 @@
10988 #include <linux/seq_file.h>
10989 #include <linux/dnotify.h>
10990 #include <linux/crc32.h>
10991+#include <linux/grsecurity.h>
10992 #include <asm/checksum.h>
10993
10994 #if defined(CONFIG_PROC_FS)
10995@@ -600,3 +601,9 @@
10996 /* To match ksyms with System.map */
10997 extern const char _end[];
10998 EXPORT_SYMBOL(_end);
10999+
11000+/* grsecurity */
11001+EXPORT_SYMBOL(gr_is_capable);
11002+EXPORT_SYMBOL(gr_pid_is_chrooted);
11003+EXPORT_SYMBOL(gr_learn_resource);
11004+EXPORT_SYMBOL(gr_set_kernel_label);
11005diff -urN linux-2.4.22/kernel/module.c linux-2.4.22/kernel/module.c
11006--- linux-2.4.22/kernel/module.c 2003-09-01 22:19:01.000000000 -0400
11007+++ linux-2.4.22/kernel/module.c 2003-09-02 19:29:42.000000000 -0400
11008@@ -900,6 +900,11 @@
11009 struct module *mod;
11010 int err;
11011
11012+#ifdef CONFIG_GRKERNSEC_HIDESYM
11013+ if (!capable(CAP_SYS_MODULE))
11014+ return -EPERM;
11015+#endif
11016+
11017 lock_kernel();
11018 if (name_user == NULL)
11019 mod = &kernel_module;
11020@@ -969,6 +974,11 @@
11021 int i;
11022 struct kernel_sym ksym;
11023
11024+#ifdef CONFIG_GRKERNSEC_HIDESYM
11025+ if (!capable(CAP_SYS_MODULE))
11026+ return 0;
11027+#endif
11028+
11029 lock_kernel();
11030 for (mod = module_list, i = 0; mod; mod = mod->next) {
11031 /* include the count for the module name! */
11032diff -urN linux-2.4.22/kernel/printk.c linux-2.4.22/kernel/printk.c
11033--- linux-2.4.22/kernel/printk.c 2003-09-01 22:19:01.000000000 -0400
11034+++ linux-2.4.22/kernel/printk.c 2003-09-02 19:29:42.000000000 -0400
11035@@ -26,6 +26,7 @@
11036 #include <linux/interrupt.h> /* For in_interrupt() */
11037 #include <linux/config.h>
11038 #include <linux/delay.h>
11039+#include <linux/grsecurity.h>
11040
11041 #include <asm/uaccess.h>
11042
11043@@ -294,6 +295,11 @@
11044
11045 asmlinkage long sys_syslog(int type, char * buf, int len)
11046 {
11047+#ifdef CONFIG_GRKERNSEC_DMESG
11048+ if (!capable(CAP_SYS_ADMIN) && grsec_enable_dmesg)
11049+ return -EPERM;
11050+ else
11051+#endif
11052 if ((type != 3) && !capable(CAP_SYS_ADMIN))
11053 return -EPERM;
11054 return do_syslog(type, buf, len);
11055diff -urN linux-2.4.22/kernel/sched.c linux-2.4.22/kernel/sched.c
11056--- linux-2.4.22/kernel/sched.c 2003-09-01 22:19:01.000000000 -0400
11057+++ linux-2.4.22/kernel/sched.c 2003-09-02 19:29:42.000000000 -0400
11058@@ -22,11 +22,13 @@
11059 #include <linux/nmi.h>
11060 #include <linux/interrupt.h>
11061 #include <linux/init.h>
11062+#include <linux/file.h>
11063 #include <asm/uaccess.h>
11064 #include <linux/smp_lock.h>
11065 #include <asm/mmu_context.h>
11066 #include <linux/kernel_stat.h>
11067 #include <linux/completion.h>
11068+#include <linux/grsecurity.h>
11069
11070 /*
11071 * Convert user-nice values [ -20 ... 0 ... 19 ]
11072@@ -910,6 +912,9 @@
11073 return -EPERM;
11074 if (increment < -40)
11075 increment = -40;
11076+
11077+ if (gr_handle_chroot_nice())
11078+ return -EPERM;
11079 }
11080 if (increment > 40)
11081 increment = 40;
11082diff -urN linux-2.4.22/kernel/signal.c linux-2.4.22/kernel/signal.c
11083--- linux-2.4.22/kernel/signal.c 2003-09-01 22:19:01.000000000 -0400
11084+++ linux-2.4.22/kernel/signal.c 2003-09-02 19:29:42.000000000 -0400
11085@@ -13,6 +13,8 @@
11086 #include <linux/smp_lock.h>
11087 #include <linux/init.h>
11088 #include <linux/sched.h>
11089+#include <linux/fs.h>
11090+#include <linux/grsecurity.h>
11091
11092 #include <asm/uaccess.h>
11093
11094@@ -554,6 +556,8 @@
11095 if (!sig || !t->sig)
11096 goto out_nolock;
11097
11098+ gr_log_signal(sig, t);
11099+
11100 spin_lock_irqsave(&t->sigmask_lock, flags);
11101 handle_stop_signal(sig, t);
11102
11103@@ -603,6 +607,8 @@
11104 recalc_sigpending(t);
11105 spin_unlock_irqrestore(&t->sigmask_lock, flags);
11106
11107+ gr_handle_crash(t, sig);
11108+
11109 return send_sig_info(sig, info, t);
11110 }
11111
11112@@ -622,9 +628,13 @@
11113 read_lock(&tasklist_lock);
11114 for_each_task(p) {
11115 if (p->pgrp == pgrp && thread_group_leader(p)) {
11116- int err = send_sig_info(sig, info, p);
11117- if (retval)
11118- retval = err;
11119+ if (gr_handle_signal(p, sig))
11120+ retval = -EPERM;
11121+ else {
11122+ int err = send_sig_info(sig, info, p);
11123+ if (retval)
11124+ retval = err;
11125+ }
11126 }
11127 }
11128 read_unlock(&tasklist_lock);
11129@@ -675,7 +685,10 @@
11130 if (tg)
11131 p = tg;
11132 }
11133- error = send_sig_info(sig, info, p);
11134+ if (gr_handle_signal(p, sig))
11135+ error = -EPERM;
11136+ else
11137+ error = send_sig_info(sig, info, p);
11138 }
11139 read_unlock(&tasklist_lock);
11140 return error;
11141@@ -700,10 +713,14 @@
11142 read_lock(&tasklist_lock);
11143 for_each_task(p) {
11144 if (p->pid > 1 && p != current && thread_group_leader(p)) {
11145- int err = send_sig_info(sig, info, p);
11146- ++count;
11147- if (err != -EPERM)
11148- retval = err;
11149+ if (gr_handle_signal(p, sig))
11150+ retval = -EPERM;
11151+ else {
11152+ int err = send_sig_info(sig, info, p);
11153+ ++count;
11154+ if (err != -EPERM)
11155+ retval = err;
11156+ }
11157 }
11158 }
11159 read_unlock(&tasklist_lock);
11160diff -urN linux-2.4.22/kernel/sys.c linux-2.4.22/kernel/sys.c
11161--- linux-2.4.22/kernel/sys.c 2003-09-01 22:19:01.000000000 -0400
11162+++ linux-2.4.22/kernel/sys.c 2003-09-02 19:29:42.000000000 -0400
11163@@ -4,6 +4,7 @@
11164 * Copyright (C) 1991, 1992 Linus Torvalds
11165 */
11166
11167+#include <linux/config.h>
11168 #include <linux/module.h>
11169 #include <linux/mm.h>
11170 #include <linux/utsname.h>
11171@@ -14,6 +15,7 @@
11172 #include <linux/prctl.h>
11173 #include <linux/init.h>
11174 #include <linux/highuid.h>
11175+#include <linux/grsecurity.h>
11176
11177 #include <asm/uaccess.h>
11178 #include <asm/io.h>
11179@@ -239,6 +241,12 @@
11180 }
11181 if (error == -ESRCH)
11182 error = 0;
11183+
11184+ if (gr_handle_chroot_setpriority(p, niceval)) {
11185+ read_unlock(&tasklist_lock);
11186+ return -ESRCH;
11187+ }
11188+
11189 if (niceval < task_nice(p) && !capable(CAP_SYS_NICE))
11190 error = -EACCES;
11191 else
11192@@ -425,6 +433,9 @@
11193 if (rgid != (gid_t) -1 ||
11194 (egid != (gid_t) -1 && egid != old_rgid))
11195 current->sgid = new_egid;
11196+
11197+ gr_set_role_label(current, current->uid, new_rgid);
11198+
11199 current->fsgid = new_egid;
11200 current->egid = new_egid;
11201 current->gid = new_rgid;
11202@@ -447,6 +458,9 @@
11203 current->mm->dumpable=0;
11204 wmb();
11205 }
11206+
11207+ gr_set_role_label(current, current->uid, gid);
11208+
11209 current->gid = current->egid = current->sgid = current->fsgid = gid;
11210 }
11211 else if ((gid == current->gid) || (gid == current->sgid))
11212@@ -530,6 +544,9 @@
11213 current->mm->dumpable = 0;
11214 wmb();
11215 }
11216+
11217+ gr_set_role_label(current, new_ruid, current->gid);
11218+
11219 current->uid = new_ruid;
11220 current->user = new_user;
11221 free_uid(old_user);
11222@@ -626,6 +643,9 @@
11223 } else if ((uid != current->uid) && (uid != new_suid))
11224 return -EPERM;
11225
11226+ if (gr_check_crash_uid(uid))
11227+ return -EPERM;
11228+
11229 if (old_euid != uid)
11230 {
11231 current->mm->dumpable = 0;
11232@@ -722,8 +742,10 @@
11233 current->egid = egid;
11234 }
11235 current->fsgid = current->egid;
11236- if (rgid != (gid_t) -1)
11237+ if (rgid != (gid_t) -1) {
11238+ gr_set_role_label(current, current->uid, rgid);
11239 current->gid = rgid;
11240+ }
11241 if (sgid != (gid_t) -1)
11242 current->sgid = sgid;
11243 return 0;
11244@@ -1146,6 +1168,10 @@
11245 if (new_rlim.rlim_cur > new_rlim.rlim_max)
11246 return -EINVAL;
11247 old_rlim = current->rlim + resource;
11248+
11249+ if (old_rlim->rlim_max < old_rlim->rlim_cur)
11250+ return -EINVAL;
11251+
11252 if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
11253 (new_rlim.rlim_max > old_rlim->rlim_max)) &&
11254 !capable(CAP_SYS_RESOURCE))
11255diff -urN linux-2.4.22/kernel/sysctl.c linux-2.4.22/kernel/sysctl.c
11256--- linux-2.4.22/kernel/sysctl.c 2003-09-01 22:19:01.000000000 -0400
11257+++ linux-2.4.22/kernel/sysctl.c 2003-09-02 19:29:42.000000000 -0400
11258@@ -38,6 +38,15 @@
11259 #endif
11260
11261 #if defined(CONFIG_SYSCTL)
11262+#include <linux/grsecurity.h>
11263+#include <linux/grinternal.h>
11264+
11265+extern int gr_proc_handler(ctl_table * table, int write, struct file * filp,
11266+ void * buffer, size_t * lenp);
11267+extern __u32 gr_handle_sysctl(const ctl_table * table, const void *oldval,
11268+ const void *newval);
11269+extern int gr_handle_sysctl_mod(const char *dirname, const char *name, const int op);
11270+extern int gr_handle_chroot_sysctl(const int op);
11271
11272 /* External variables not in a header file. */
11273 extern int panic_timeout;
11274@@ -123,6 +132,8 @@
11275 static ctl_table dev_table[];
11276 extern ctl_table random_table[];
11277
11278+static ctl_table grsecurity_table[];
11279+
11280 /* /proc declarations: */
11281
11282 #ifdef CONFIG_PROC_FS
11283@@ -269,8 +280,191 @@
11284 {KERN_EXCEPTION_TRACE,"exception-trace",
11285 &exception_trace,sizeof(int),0644,NULL,&proc_dointvec},
11286 #endif
11287+#ifdef CONFIG_GRKERNSEC_SYSCTL
11288+ {KERN_GRSECURITY, "grsecurity", NULL, 0, 0500, grsecurity_table},
11289+#endif
11290+ {0}
11291+};
11292+
11293+#ifdef CONFIG_GRKERNSEC_SYSCTL
11294+enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
11295+GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
11296+GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
11297+GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
11298+GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
11299+GS_RANDPID, GS_RANDID, GS_RANDSRC, GS_RANDISN,
11300+GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
11301+GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, GS_TTY, GS_TTYS,
11302+GS_PTY, GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG, GS_RANDRPC,
11303+GS_FINDTASK, GS_LOCK};
11304+
11305+static ctl_table grsecurity_table[] = {
11306+#ifdef CONFIG_GRKERNSEC_LINK
11307+ {GS_LINK, "linking_restrictions", &grsec_enable_link, sizeof (int),
11308+ 0600, NULL, &proc_dointvec},
11309+#endif
11310+#ifdef CONFIG_GRKERNSEC_FIFO
11311+ {GS_FIFO, "fifo_restrictions", &grsec_enable_fifo, sizeof (int),
11312+ 0600, NULL, &proc_dointvec},
11313+#endif
11314+#ifdef CONFIG_GRKERNSEC_EXECVE
11315+ {GS_EXECVE, "execve_limiting", &grsec_enable_execve, sizeof (int),
11316+ 0600, NULL, &proc_dointvec},
11317+#endif
11318+#ifdef CONFIG_GRKERNSEC_EXECLOG
11319+ {GS_EXECLOG, "exec_logging", &grsec_enable_execlog, sizeof (int),
11320+ 0600, NULL, &proc_dointvec},
11321+#endif
11322+#ifdef CONFIG_GRKERNSEC_SIGNAL
11323+ {GS_SIGNAL, "signal_logging", &grsec_enable_signal, sizeof (int),
11324+ 0600, NULL, &proc_dointvec},
11325+#endif
11326+#ifdef CONFIG_GRKERNSEC_FORKFAIL
11327+ {GS_FORKFAIL, "forkfail_logging", &grsec_enable_forkfail, sizeof (int),
11328+ 0600, NULL, &proc_dointvec},
11329+#endif
11330+#ifdef CONFIG_GRKERNSEC_TIME
11331+ {GS_TIME, "timechange_logging", &grsec_enable_time, sizeof (int),
11332+ 0600, NULL, &proc_dointvec},
11333+#endif
11334+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
11335+ {GS_CHROOT_SHMAT, "chroot_deny_shmat", &grsec_enable_chroot_shmat, sizeof (int),
11336+ 0600, NULL, &proc_dointvec},
11337+#endif
11338+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
11339+ {GS_CHROOT_UNIX, "chroot_deny_unix", &grsec_enable_chroot_unix, sizeof(int),
11340+ 0600, NULL, &proc_dointvec},
11341+#endif
11342+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
11343+ {GS_CHROOT_MNT, "chroot_deny_mount", &grsec_enable_chroot_mount, sizeof (int),
11344+ 0600, NULL, &proc_dointvec},
11345+#endif
11346+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
11347+ {GS_CHROOT_FCHDIR, "chroot_deny_fchdir", &grsec_enable_chroot_fchdir, sizeof (int),
11348+ 0600, NULL, &proc_dointvec},
11349+#endif
11350+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
11351+ {GS_CHROOT_DBL, "chroot_deny_chroot", &grsec_enable_chroot_double, sizeof (int),
11352+ 0600, NULL, &proc_dointvec},
11353+#endif
11354+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
11355+ {GS_CHROOT_PVT, "chroot_deny_pivot", &grsec_enable_chroot_pivot, sizeof (int),
11356+ 0600, NULL, &proc_dointvec},
11357+#endif
11358+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
11359+ {GS_CHROOT_CD, "chroot_enforce_chdir", &grsec_enable_chroot_chdir, sizeof (int),
11360+ 0600, NULL, &proc_dointvec},
11361+#endif
11362+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
11363+ {GS_CHROOT_CM, "chroot_deny_chmod", &grsec_enable_chroot_chmod, sizeof (int),
11364+ 0600, NULL, &proc_dointvec},
11365+#endif
11366+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
11367+ {GS_CHROOT_MK, "chroot_deny_mknod", &grsec_enable_chroot_mknod, sizeof (int),
11368+ 0600, NULL, &proc_dointvec},
11369+#endif
11370+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
11371+ {GS_CHROOT_NI, "chroot_restrict_nice", &grsec_enable_chroot_nice, sizeof (int),
11372+ 0600, NULL, &proc_dointvec},
11373+#endif
11374+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
11375+ {GS_CHROOT_EXECLOG, "chroot_execlog",
11376+ &grsec_enable_chroot_execlog, sizeof (int),
11377+ 0600, NULL, &proc_dointvec},
11378+#endif
11379+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
11380+ {GS_CHROOT_CAPS, "chroot_caps", &grsec_enable_chroot_caps, sizeof (int),
11381+ 0600, NULL, &proc_dointvec},
11382+#endif
11383+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
11384+ {GS_CHROOT_SYSCTL, "chroot_deny_sysctl", &grsec_enable_chroot_sysctl, sizeof (int),
11385+ 0600, NULL, &proc_dointvec},
11386+#endif
11387+#ifdef CONFIG_GRKERNSEC_TPE
11388+ {GS_TPE, "tpe", &grsec_enable_tpe, sizeof (int),
11389+ 0600, NULL, &proc_dointvec},
11390+ {GS_TPE_GID, "tpe_gid", &grsec_tpe_gid, sizeof (int),
11391+ 0600, NULL, &proc_dointvec},
11392+#endif
11393+#ifdef CONFIG_GRKERNSEC_TPE_ALL
11394+ {GS_TPE_ALL, "tpe_restrict_all", &grsec_enable_tpe_all, sizeof (int),
11395+ 0600, NULL, &proc_dointvec},
11396+#endif
11397+#ifdef CONFIG_GRKERNSEC_RANDPID
11398+ {GS_RANDPID, "rand_pids", &grsec_enable_randpid, sizeof (int),
11399+ 0600, NULL, &proc_dointvec},
11400+#endif
11401+#ifdef CONFIG_GRKERNSEC_RANDID
11402+ {GS_RANDID, "rand_ip_ids", &grsec_enable_randid, sizeof (int),
11403+ 0600, NULL, &proc_dointvec},
11404+#endif
11405+#ifdef CONFIG_GRKERNSEC_RANDSRC
11406+ {GS_RANDSRC, "rand_tcp_src_ports", &grsec_enable_randsrc, sizeof (int),
11407+ 0600, NULL, &proc_dointvec},
11408+#endif
11409+#ifdef CONFIG_GRKERNSEC_RANDISN
11410+ {GS_RANDISN, "rand_isns", &grsec_enable_randisn, sizeof (int),
11411+ 0600, NULL, &proc_dointvec},
11412+#endif
11413+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
11414+ {GS_SOCKET_ALL, "socket_all", &grsec_enable_socket_all, sizeof (int),
11415+ 0600, NULL, &proc_dointvec},
11416+ {GS_SOCKET_ALL_GID, "socket_all_gid",
11417+ &grsec_socket_all_gid, sizeof (int),
11418+ 0600, NULL, &proc_dointvec},
11419+#endif
11420+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
11421+ {GS_SOCKET_CLIENT, "socket_client",
11422+ &grsec_enable_socket_client, sizeof (int),
11423+ 0600, NULL, &proc_dointvec},
11424+ {GS_SOCKET_CLIENT_GID, "socket_client_gid",
11425+ &grsec_socket_client_gid, sizeof (int),
11426+ 0600, NULL, &proc_dointvec},
11427+#endif
11428+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
11429+ {GS_SOCKET_SERVER, "socket_server",
11430+ &grsec_enable_socket_server, sizeof (int),
11431+ 0600, NULL, &proc_dointvec},
11432+ {GS_SOCKET_SERVER_GID, "socket_server_gid",
11433+ &grsec_socket_server_gid, sizeof (int),
11434+ 0600, NULL, &proc_dointvec},
11435+#endif
11436+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
11437+ {GS_GROUP, "audit_group", &grsec_enable_group, sizeof (int),
11438+ 0600, NULL, &proc_dointvec},
11439+ {GS_GID, "audit_gid",
11440+ &grsec_audit_gid, sizeof (int),
11441+ 0600, NULL, &proc_dointvec},
11442+#endif
11443+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
11444+ {GS_ACHDIR, "audit_chdir", &grsec_enable_chdir, sizeof (int),
11445+ 0600, NULL, &proc_dointvec},
11446+#endif
11447+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
11448+ {GS_AMOUNT, "audit_mount", &grsec_enable_mount, sizeof (int),
11449+ 0600, NULL, &proc_dointvec},
11450+#endif
11451+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
11452+ {GS_AIPC, "audit_ipc", &grsec_enable_audit_ipc, sizeof (int),
11453+ 0600, NULL, &proc_dointvec},
11454+#endif
11455+#ifdef CONFIG_GRKERNSEC_DMESG
11456+ {GS_AIPC, "dmesg", &grsec_enable_dmesg, sizeof (int),
11457+ 0600, NULL, &proc_dointvec},
11458+#endif
11459+#ifdef CONFIG_GRKERNSEC_RANDRPC
11460+ {GS_RANDRPC, "rand_rpc", &grsec_enable_randrpc, sizeof (int),
11461+ 0600, NULL, &proc_dointvec},
11462+#endif
11463+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
11464+ {GS_FINDTASK, "chroot_findtask", &grsec_enable_chroot_findtask,
11465+ sizeof (int), 0600, NULL, &proc_dointvec},
11466+#endif
11467+ {GS_LOCK, "grsec_lock", &grsec_lock, sizeof (int), 0600, NULL,
11468+ &proc_dointvec},
11469 {0}
11470 };
11471+#endif
11472
11473 static ctl_table vm_table[] = {
11474 {VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0644, NULL,
11475@@ -403,6 +597,11 @@
11476
11477 static inline int ctl_perm(ctl_table *table, int op)
11478 {
11479+ if (gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
11480+ return -EACCES;
11481+ if (gr_handle_chroot_sysctl(op))
11482+ return -EACCES;
11483+
11484 return test_perm(table->mode, op);
11485 }
11486
11487@@ -436,6 +635,10 @@
11488 table = table->child;
11489 goto repeat;
11490 }
11491+
11492+ if (!gr_handle_sysctl(table, oldval, newval))
11493+ return -EACCES;
11494+
11495 error = do_sysctl_strategy(table, name, nlen,
11496 oldval, oldlenp,
11497 newval, newlen, context);
11498diff -urN linux-2.4.22/kernel/time.c linux-2.4.22/kernel/time.c
11499--- linux-2.4.22/kernel/time.c 2003-09-01 22:19:01.000000000 -0400
11500+++ linux-2.4.22/kernel/time.c 2003-09-02 19:29:42.000000000 -0400
11501@@ -27,6 +27,7 @@
11502 #include <linux/mm.h>
11503 #include <linux/timex.h>
11504 #include <linux/smp_lock.h>
11505+#include <linux/grsecurity.h>
11506
11507 #include <asm/uaccess.h>
11508
11509@@ -89,6 +90,9 @@
11510 time_maxerror = NTP_PHASE_LIMIT;
11511 time_esterror = NTP_PHASE_LIMIT;
11512 write_unlock_irq(&xtime_lock);
11513+
11514+ gr_log_timechange();
11515+
11516 return 0;
11517 }
11518
11519@@ -167,6 +171,8 @@
11520 * globally block out interrupts when it runs.
11521 */
11522 do_settimeofday(tv);
11523+
11524+ gr_log_timechange();
11525 }
11526 return 0;
11527 }
11528diff -urN linux-2.4.22/kernel/timer.c linux-2.4.22/kernel/timer.c
11529--- linux-2.4.22/kernel/timer.c 2003-09-01 22:19:01.000000000 -0400
11530+++ linux-2.4.22/kernel/timer.c 2003-09-02 19:29:42.000000000 -0400
11531@@ -541,6 +541,9 @@
11532
11533 psecs = (p->times.tms_utime += user);
11534 psecs += (p->times.tms_stime += system);
11535+
11536+ gr_learn_resource(p, RLIMIT_CPU, psecs / HZ);
11537+
11538 if (psecs / HZ > p->rlim[RLIMIT_CPU].rlim_cur) {
11539 /* Send SIGXCPU every second.. */
11540 if (!(psecs % HZ))
11541diff -urN linux-2.4.22/mm/filemap.c linux-2.4.22/mm/filemap.c
11542--- linux-2.4.22/mm/filemap.c 2003-09-01 22:19:02.000000000 -0400
11543+++ linux-2.4.22/mm/filemap.c 2003-09-02 19:29:42.000000000 -0400
11544@@ -2541,6 +2547,7 @@
11545 error = -EIO;
11546 rlim_rss = current->rlim ? current->rlim[RLIMIT_RSS].rlim_cur :
11547 LONG_MAX; /* default: see resource.h */
11548+ gr_learn_resource(current, RLIMIT_RSS, vma->vm_mm->rss + (end - start));
11549 if ((vma->vm_mm->rss + (end - start)) > rlim_rss)
11550 return error;
11551
11552@@ -3016,6 +3023,7 @@
11553 err = -EFBIG;
11554
11555 if (!S_ISBLK(inode->i_mode) && limit != RLIM_INFINITY) {
11556+ gr_learn_resource(current, RLIMIT_FSIZE, pos);
11557 if (pos >= limit) {
11558 send_sig(SIGXFSZ, current, 0);
11559 goto out;
11560@@ -3051,6 +3059,7 @@
11561 */
11562
11563 if (!S_ISBLK(inode->i_mode)) {
11564+ gr_learn_resource(current, RLIMIT_FSIZE, *count + (u32)pos);
11565 if (pos >= inode->i_sb->s_maxbytes)
11566 {
11567 if (*count || pos > inode->i_sb->s_maxbytes) {
11568diff -urN linux-2.4.22/mm/memory.c linux-2.4.22/mm/memory.c
11569--- linux-2.4.22/mm/memory.c 2003-09-01 22:19:02.000000000 -0400
11570+++ linux-2.4.22/mm/memory.c 2003-09-02 19:29:42.000000000 -0400
11571@@ -1065,6 +1129,7 @@
11572
11573 do_expand:
11574 limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
11575+ gr_learn_resource(current, RLIMIT_FSIZE, offset);
11576 if (limit != RLIM_INFINITY && offset > limit)
11577 goto out_sig;
11578 if (offset > inode->i_sb->s_maxbytes)
11579diff -urN linux-2.4.22/mm/mlock.c linux-2.4.22/mm/mlock.c
11580--- linux-2.4.22/mm/mlock.c 2003-09-01 22:19:02.000000000 -0400
11581+++ linux-2.4.22/mm/mlock.c 2003-09-02 19:29:42.000000000 -0400
11582@@ -209,6 +235,7 @@
11583 lock_limit >>= PAGE_SHIFT;
11584
11585 /* check against resource limits */
11586+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
11587 if (locked > lock_limit)
11588 goto out;
11589
11590@@ -276,6 +303,7 @@
11591 lock_limit >>= PAGE_SHIFT;
11592
11593 ret = -ENOMEM;
11594+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm);
11595 if (current->mm->total_vm > lock_limit)
11596 goto out;
11597
11598diff -urN linux-2.4.22/mm/mmap.c linux-2.4.22/mm/mmap.c
11599--- linux-2.4.22/mm/mmap.c 2003-09-01 22:19:02.000000000 -0400
11600+++ linux-2.4.22/mm/mmap.c 2003-09-02 19:29:42.000000000 -0400
11601@@ -14,6 +14,8 @@
11602 #include <linux/file.h>
11603 #include <linux/fs.h>
11604 #include <linux/personality.h>
11605+#include <linux/random.h>
11606+#include <linux/grsecurity.h>
11607
11608 #include <asm/uaccess.h>
11609 #include <asm/pgalloc.h>
11610@@ -168,6 +170,7 @@
11611
11612 /* Check against rlimit.. */
11613 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
11614+ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data);
11615 if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
11616 goto out;
11617
11618@@ -432,6 +462,7 @@
11619 if (vm_flags & VM_LOCKED) {
11620 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
11621 locked += len;
11622+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
11623 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
11624 return -EAGAIN;
11625 }
11626@@ -480,6 +532,9 @@
11627 }
11628 }
11629
11630+ if (!gr_acl_handle_mmap(file, prot))
11631+ return -EACCES;
11632+
11633 /* Clear old maps */
11634 munmap_back:
11635 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
11636@@ -490,6 +545,7 @@
11637 }
11638
11639 /* Check against address space limit. */
11640+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len);
11641 if ((mm->total_vm << PAGE_SHIFT) + len
11642 > current->rlim[RLIMIT_AS].rlim_cur)
11643 return -ENOMEM;
11644@@ -1047,6 +1255,7 @@
11645 if (mm->def_flags & VM_LOCKED) {
11646 unsigned long locked = mm->locked_vm << PAGE_SHIFT;
11647 locked += len;
11648+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
11649 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
11650 return -EAGAIN;
11651 }
11652@@ -1063,6 +1272,7 @@
11653 }
11654
11655 /* Check against address space limits *after* clearing old maps... */
11656+ gr_learn_resource(current, RLIMIT_AS, (mm->total_vm << PAGE_SHIFT) + len);
11657 if ((mm->total_vm << PAGE_SHIFT) + len
11658 > current->rlim[RLIMIT_AS].rlim_cur)
11659 return -ENOMEM;
11660diff -urN linux-2.4.22/mm/mprotect.c linux-2.4.22/mm/mprotect.c
11661--- linux-2.4.22/mm/mprotect.c 2003-09-01 22:19:02.000000000 -0400
11662+++ linux-2.4.22/mm/mprotect.c 2003-09-02 19:29:42.000000000 -0400
11663@@ -7,6 +7,7 @@
11664 #include <linux/smp_lock.h>
11665 #include <linux/shm.h>
11666 #include <linux/mman.h>
11667+#include <linux/grsecurity.h>
11668
11669 #include <asm/uaccess.h>
11670 #include <asm/pgalloc.h>
11671@@ -288,6 +393,11 @@
11672 if (!vma || vma->vm_start > start)
11673 goto out;
11674
11675+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
11676+ error = -EACCES;
11677+ goto out;
11678+ }
11679+
11680 for (nstart = start ; ; ) {
11681 unsigned int newflags;
11682 int last = 0;
11683diff -urN linux-2.4.22/mm/mremap.c linux-2.4.22/mm/mremap.c
11684--- linux-2.4.22/mm/mremap.c 2003-09-01 22:19:02.000000000 -0400
11685+++ linux-2.4.22/mm/mremap.c 2003-09-02 19:29:42.000000000 -0400
11686@@ -283,10 +305,12 @@
11687 unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
11688 locked += new_len - old_len;
11689 ret = -EAGAIN;
11690+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked);
11691 if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
11692 goto out;
11693 }
11694 ret = -ENOMEM;
11695+ gr_learn_resource(current, RLIMIT_AS, (current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len));
11696 if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
11697 > current->rlim[RLIMIT_AS].rlim_cur)
11698 goto out;
11699diff -urN linux-2.4.22/net/ipv4/af_inet.c linux-2.4.22/net/ipv4/af_inet.c
11700--- linux-2.4.22/net/ipv4/af_inet.c 2003-09-01 22:19:08.000000000 -0400
11701+++ linux-2.4.22/net/ipv4/af_inet.c 2003-09-02 19:29:42.000000000 -0400
11702@@ -83,6 +83,7 @@
11703 #include <linux/init.h>
11704 #include <linux/poll.h>
11705 #include <linux/netfilter_ipv4.h>
11706+#include <linux/grsecurity.h>
11707
11708 #include <asm/uaccess.h>
11709 #include <asm/system.h>
11710@@ -374,7 +375,12 @@
11711 else
11712 sk->protinfo.af_inet.pmtudisc = IP_PMTUDISC_WANT;
11713
11714- sk->protinfo.af_inet.id = 0;
11715+#ifdef CONFIG_GRKERNSEC_RANDID
11716+ if(grsec_enable_randid)
11717+ sk->protinfo.af_inet.id = htons(ip_randomid());
11718+ else
11719+#endif
11720+ sk->protinfo.af_inet.id = 0;
11721
11722 sock_init_data(sock,sk);
11723
11724diff -urN linux-2.4.22/net/ipv4/icmp.c linux-2.4.22/net/ipv4/icmp.c
11725--- linux-2.4.22/net/ipv4/icmp.c 2003-09-01 22:19:08.000000000 -0400
11726+++ linux-2.4.22/net/ipv4/icmp.c 2003-09-02 19:29:42.000000000 -0400
11727@@ -87,6 +87,8 @@
11728 #include <linux/errno.h>
11729 #include <linux/timer.h>
11730 #include <linux/init.h>
11731+#include <linux/grsecurity.h>
11732+
11733 #include <asm/system.h>
11734 #include <asm/uaccess.h>
11735 #include <net/checksum.h>
11736@@ -715,6 +717,7 @@
11737
11738 icmp_param.data.icmph=*skb->h.icmph;
11739 icmp_param.data.icmph.type=ICMP_ECHOREPLY;
11740+
11741 icmp_param.skb=skb;
11742 icmp_param.offset=0;
11743 icmp_param.data_len=skb->len;
11744diff -urN linux-2.4.22/net/ipv4/ip_output.c linux-2.4.22/net/ipv4/ip_output.c
11745--- linux-2.4.22/net/ipv4/ip_output.c 2003-09-01 22:19:08.000000000 -0400
11746+++ linux-2.4.22/net/ipv4/ip_output.c 2003-09-02 19:29:42.000000000 -0400
11747@@ -77,6 +77,7 @@
11748 #include <linux/netfilter_ipv4.h>
11749 #include <linux/mroute.h>
11750 #include <linux/netlink.h>
11751+#include <linux/grsecurity.h>
11752
11753 /*
11754 * Shall we try to damage output packets if routing dev changes?
11755@@ -514,7 +515,13 @@
11756 * Begin outputting the bytes.
11757 */
11758
11759- id = sk->protinfo.af_inet.id++;
11760+#ifdef CONFIG_GRKERNSEC_RANDID
11761+ if(grsec_enable_randid) {
11762+ id = htons(ip_randomid());
11763+ sk->protinfo.af_inet.id = htons(ip_randomid());
11764+ } else
11765+#endif
11766+ id = sk->protinfo.af_inet.id++;
11767
11768 do {
11769 char *data;
11770diff -urN linux-2.4.22/net/ipv4/netfilter/Config.in linux-2.4.22/net/ipv4/netfilter/Config.in
11771--- linux-2.4.22/net/ipv4/netfilter/Config.in 2003-09-01 22:19:08.000000000 -0400
11772+++ linux-2.4.22/net/ipv4/netfilter/Config.in 2003-09-02 19:29:42.000000000 -0400
11773@@ -33,6 +33,7 @@
11774 dep_tristate ' address type match support' CONFIG_IP_NF_MATCH_ADDRTYPE $CONFIG_IP_NF_IPTABLES
11775 dep_tristate ' tcpmss match support' CONFIG_IP_NF_MATCH_TCPMSS $CONFIG_IP_NF_IPTABLES
11776 dep_tristate ' realm match support' CONFIG_IP_NF_MATCH_REALM $CONFIG_IP_NF_IPTABLES
11777+ dep_tristate ' stealth match support' CONFIG_IP_NF_MATCH_STEALTH $CONFIG_IP_NF_IPTABLES
11778 if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
11779 dep_tristate ' Helper match support' CONFIG_IP_NF_MATCH_HELPER $CONFIG_IP_NF_IPTABLES
11780 fi
11781diff -urN linux-2.4.22/net/ipv4/netfilter/Makefile linux-2.4.22/net/ipv4/netfilter/Makefile
11782--- linux-2.4.22/net/ipv4/netfilter/Makefile 2003-09-01 22:19:08.000000000 -0400
11783+++ linux-2.4.22/net/ipv4/netfilter/Makefile 2003-09-02 19:29:42.000000000 -0400
11784@@ -86,6 +86,7 @@
11785 obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o
11786 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
11787 obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o
11788+obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
11789
11790 # targets
11791 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
11792diff -urN linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c
11793--- linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
11794+++ linux-2.4.22/net/ipv4/netfilter/ipt_stealth.c 2003-09-02 19:29:42.000000000 -0400
11795@@ -0,0 +1,109 @@
11796+/* Kernel module to add stealth support.
11797+ *
11798+ * Copyright (C) 2002 Brad Spengler <spender@grsecurity.net>
11799+ *
11800+ */
11801+
11802+#include <linux/kernel.h>
11803+#include <linux/module.h>
11804+#include <linux/skbuff.h>
11805+#include <linux/net.h>
11806+#include <linux/sched.h>
11807+#include <linux/inet.h>
11808+#include <linux/stddef.h>
11809+
11810+#include <net/ip.h>
11811+#include <net/sock.h>
11812+#include <net/tcp.h>
11813+#include <net/udp.h>
11814+#include <net/route.h>
11815+#include <net/inet_common.h>
11816+
11817+#include <linux/netfilter_ipv4/ip_tables.h>
11818+
11819+MODULE_LICENSE("GPL");
11820+
11821+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
11822+
11823+static int
11824+match(const struct sk_buff *skb,
11825+ const struct net_device *in,
11826+ const struct net_device *out,
11827+ const void *matchinfo,
11828+ int offset,
11829+ const void *hdr,
11830+ u_int16_t datalen,
11831+ int *hotdrop)
11832+{
11833+ struct iphdr *ip = skb->nh.iph;
11834+ struct tcphdr *th = (struct tcphdr *) hdr;
11835+ struct udphdr *uh = (struct udphdr *) hdr;
11836+ struct sock *sk = NULL;
11837+
11838+ if (!ip || !hdr || offset) return 0;
11839+
11840+ switch(ip->protocol) {
11841+ case IPPROTO_TCP:
11842+ if (datalen < sizeof(struct tcphdr)) {
11843+ *hotdrop = 1;
11844+ return 0;
11845+ }
11846+ if (!(th->syn && !th->ack)) return 0;
11847+ sk = tcp_v4_lookup_listener(ip->daddr, ntohs(th->dest), ((struct rtable*)skb->dst)->rt_iif);
11848+ break;
11849+ case IPPROTO_UDP:
11850+ if (datalen < sizeof(struct udphdr)) {
11851+ *hotdrop = 1;
11852+ return 0;
11853+ }
11854+ sk = udp_v4_lookup(ip->saddr, uh->source, ip->daddr, uh->dest, skb->dev->ifindex);
11855+ break;
11856+ default:
11857+ return 0;
11858+ }
11859+
11860+ if(!sk) // port is being listened on, match this
11861+ return 1;
11862+ else {
11863+ sock_put(sk);
11864+ return 0;
11865+ }
11866+}
11867+
11868+/* Called when user tries to insert an entry of this type. */
11869+static int
11870+checkentry(const char *tablename,
11871+ const struct ipt_ip *ip,
11872+ void *matchinfo,
11873+ unsigned int matchsize,
11874+ unsigned int hook_mask)
11875+{
11876+ if (matchsize != IPT_ALIGN(0))
11877+ return 0;
11878+
11879+ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
11880+ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
11881+ && (hook_mask & (1 << NF_IP_LOCAL_IN)))
11882+ return 1;
11883+
11884+ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
11885+
11886+ return 0;
11887+}
11888+
11889+
11890+static struct ipt_match stealth_match
11891+= { { NULL, NULL }, "stealth", &match, &checkentry, NULL, THIS_MODULE };
11892+
11893+static int __init init(void)
11894+{
11895+ return ipt_register_match(&stealth_match);
11896+}
11897+
11898+static void __exit fini(void)
11899+{
11900+ ipt_unregister_match(&stealth_match);
11901+}
11902+
11903+module_init(init);
11904+module_exit(fini);
11905diff -urN linux-2.4.22/net/ipv4/tcp_ipv4.c linux-2.4.22/net/ipv4/tcp_ipv4.c
11906--- linux-2.4.22/net/ipv4/tcp_ipv4.c 2003-09-01 22:19:08.000000000 -0400
11907+++ linux-2.4.22/net/ipv4/tcp_ipv4.c 2003-09-02 19:29:42.000000000 -0400
11908@@ -67,6 +67,7 @@
11909 #include <linux/inet.h>
11910 #include <linux/stddef.h>
11911 #include <linux/ipsec.h>
11912+#include <linux/grsecurity.h>
11913
11914 extern int sysctl_ip_dynaddr;
11915 extern int sysctl_ip_default_ttl;
11916@@ -221,9 +222,18 @@
11917
11918 spin_lock(&tcp_portalloc_lock);
11919 rover = tcp_port_rover;
11920- do { rover++;
11921- if ((rover < low) || (rover > high))
11922- rover = low;
11923+ do {
11924+#ifdef CONFIG_GRKERNSEC_RANDSRC
11925+ if (grsec_enable_randsrc && (high > low)) {
11926+ rover = low + (get_random_long() % (high - low));
11927+ } else
11928+#endif
11929+ {
11930+ rover++;
11931+ if ((rover < low) || (rover > high))
11932+ rover = low;
11933+ }
11934+
11935 head = &tcp_bhash[tcp_bhashfn(rover)];
11936 spin_lock(&head->lock);
11937 for (tb = head->chain; tb; tb = tb->next)
11938@@ -546,6 +556,11 @@
11939
11940 static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
11941 {
11942+#ifdef CONFIG_GRKERNSEC_RANDISN
11943+ if (likely(grsec_enable_randisn))
11944+ return ip_randomisn();
11945+ else
11946+#endif
11947 return secure_tcp_sequence_number(skb->nh.iph->daddr,
11948 skb->nh.iph->saddr,
11949 skb->h.th->dest,
11950@@ -681,9 +696,16 @@
11951 rover = tcp_port_rover;
11952
11953 do {
11954- rover++;
11955- if ((rover < low) || (rover > high))
11956- rover = low;
11957+#ifdef CONFIG_GRKERNSEC_RANDSRC
11958+ if(grsec_enable_randsrc && (high > low)) {
11959+ rover = low + (get_random_long() % (high - low));
11960+ } else
11961+#endif
11962+ {
11963+ rover++;
11964+ if ((rover < low) || (rover > high))
11965+ rover = low;
11966+ }
11967 head = &tcp_bhash[tcp_bhashfn(rover)];
11968 spin_lock(&head->lock);
11969
11970@@ -844,11 +866,22 @@
11971 if (err)
11972 goto failure;
11973
11974- if (!tp->write_seq)
11975+ if (!tp->write_seq) {
11976+#ifdef CONFIG_GRKERNSEC_RANDISN
11977+ if (likely(grsec_enable_randisn))
11978+ tp->write_seq = ip_randomisn();
11979+ else
11980+#endif
11981 tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
11982 sk->sport, usin->sin_port);
11983+ }
11984
11985- sk->protinfo.af_inet.id = tp->write_seq^jiffies;
11986+#ifdef CONFIG_GRKERNSEC_RANDID
11987+ if(grsec_enable_randid)
11988+ sk->protinfo.af_inet.id = htons(ip_randomid());
11989+ else
11990+#endif
11991+ sk->protinfo.af_inet.id = tp->write_seq^jiffies;
11992
11993 err = tcp_connect(sk);
11994 if (err)
11995@@ -1570,7 +1603,13 @@
11996 newtp->ext_header_len = 0;
11997 if (newsk->protinfo.af_inet.opt)
11998 newtp->ext_header_len = newsk->protinfo.af_inet.opt->optlen;
11999- newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
12000+
12001+#ifdef CONFIG_GRKERNSEC_RANDID
12002+ if(grsec_enable_randid)
12003+ newsk->protinfo.af_inet.id = htons(ip_randomid());
12004+ else
12005+#endif
12006+ newsk->protinfo.af_inet.id = newtp->write_seq^jiffies;
12007
12008 tcp_sync_mss(newsk, dst->pmtu);
12009 newtp->advmss = dst->advmss;
12010diff -urN linux-2.4.22/net/ipv4/udp.c linux-2.4.22/net/ipv4/udp.c
12011--- linux-2.4.22/net/ipv4/udp.c 2003-09-01 22:19:08.000000000 -0400
12012+++ linux-2.4.22/net/ipv4/udp.c 2003-09-02 19:29:42.000000000 -0400
12013@@ -91,6 +91,7 @@
12014 #include <net/ipv6.h>
12015 #include <net/protocol.h>
12016 #include <linux/skbuff.h>
12017+#include <linux/grsecurity.h>
12018 #include <net/sock.h>
12019 #include <net/udp.h>
12020 #include <net/icmp.h>
12021@@ -98,6 +99,11 @@
12022 #include <net/inet_common.h>
12023 #include <net/checksum.h>
12024
12025+extern int gr_search_udp_recvmsg(const struct sock *sk,
12026+ const struct sk_buff *skb);
12027+extern int gr_search_udp_sendmsg(const struct sock *sk,
12028+ const struct sockaddr_in *addr);
12029+
12030 /*
12031 * Snmp MIB for the UDP layer
12032 */
12033@@ -478,9 +484,16 @@
12034 ufh.uh.dest = usin->sin_port;
12035 if (ufh.uh.dest == 0)
12036 return -EINVAL;
12037+
12038+ if (!gr_search_udp_sendmsg(sk, usin))
12039+ return -EPERM;
12040 } else {
12041 if (sk->state != TCP_ESTABLISHED)
12042 return -EDESTADDRREQ;
12043+
12044+ if (!gr_search_udp_sendmsg(sk, NULL))
12045+ return -EPERM;
12046+
12047 ufh.daddr = sk->daddr;
12048 ufh.uh.dest = sk->dport;
12049 /* Open fast path for connected socket.
12050@@ -488,6 +501,7 @@
12051 */
12052 connected = 1;
12053 }
12054+
12055 ipc.addr = sk->saddr;
12056 ufh.uh.source = sk->sport;
12057
12058@@ -659,6 +673,11 @@
12059 if (!skb)
12060 goto out;
12061
12062+ if (!gr_search_udp_recvmsg(sk, skb)) {
12063+ err = -EPERM;
12064+ goto out_free;
12065+ }
12066+
12067 copied = skb->len - sizeof(struct udphdr);
12068 if (copied > len) {
12069 copied = len;
12070@@ -763,7 +782,13 @@
12071 sk->daddr = rt->rt_dst;
12072 sk->dport = usin->sin_port;
12073 sk->state = TCP_ESTABLISHED;
12074- sk->protinfo.af_inet.id = jiffies;
12075+
12076+#ifdef CONFIG_GRKERNSEC_RANDID
12077+ if(grsec_enable_randid)
12078+ sk->protinfo.af_inet.id = htons(ip_randomid());
12079+ else
12080+#endif
12081+ sk->protinfo.af_inet.id = jiffies;
12082
12083 sk_dst_set(sk, &rt->u.dst);
12084 return(0);
12085diff -urN linux-2.4.22/net/netlink/af_netlink.c linux-2.4.22/net/netlink/af_netlink.c
12086--- linux-2.4.22/net/netlink/af_netlink.c 2003-09-01 22:19:11.000000000 -0400
12087+++ linux-2.4.22/net/netlink/af_netlink.c 2003-09-02 19:29:42.000000000 -0400
12088@@ -40,6 +40,7 @@
12089 #include <linux/proc_fs.h>
12090 #include <linux/smp_lock.h>
12091 #include <linux/notifier.h>
12092+#include <linux/grsecurity.h>
12093 #include <net/sock.h>
12094 #include <net/scm.h>
12095
12096@@ -625,7 +626,8 @@
12097 check them, when this message will be delivered
12098 to corresponding kernel module. --ANK (980802)
12099 */
12100- NETLINK_CB(skb).eff_cap = current->cap_effective;
12101+
12102+ NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink();
12103
12104 err = -EFAULT;
12105 if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) {
12106diff -urN linux-2.4.22/net/netsyms.c linux-2.4.22/net/netsyms.c
12107--- linux-2.4.22/net/netsyms.c 2003-09-01 22:19:08.000000000 -0400
12108+++ linux-2.4.22/net/netsyms.c 2003-09-02 19:29:42.000000000 -0400
12109@@ -24,6 +24,7 @@
12110 #include <net/checksum.h>
12111 #include <linux/etherdevice.h>
12112 #include <net/route.h>
12113+#include <linux/grsecurity.h>
12114 #ifdef CONFIG_HIPPI
12115 #include <linux/hippidevice.h>
12116 #endif
60e7c427 12117@@ -606,6 +607,47 @@
ada7ca3f
JR
12118
12119 EXPORT_SYMBOL(softnet_data);
12120
12121+#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
12122+#if !defined (CONFIG_IPV6_MODULE) && !defined (CONFIG_KHTTPD) && !defined (CONFIG_KHTTPD_MODULE)
12123+EXPORT_SYMBOL(tcp_v4_lookup_listener);
12124+#endif
ada7ca3f
JR
12125+#endif
12126+
12127+#if defined(CONFIG_GRKERNSEC_RANDID)
12128+EXPORT_SYMBOL(ip_randomid);
12129+#endif
12130+#if defined(CONFIG_GRKERNSEC_RANDSRC) || defined(CONFIG_GRKERNSEC_RANDRPC)
12131+EXPORT_SYMBOL(get_random_long);
12132+#endif
12133+#ifdef CONFIG_GRKERNSEC_RANDISN
12134+EXPORT_SYMBOL(ip_randomisn);
12135+EXPORT_SYMBOL(grsec_enable_randisn);
12136+#endif
12137+#ifdef CONFIG_GRKERNSEC_RANDID
12138+EXPORT_SYMBOL(grsec_enable_randid);
12139+#endif
12140+#ifdef CONFIG_GRKERNSEC_RANDSRC
12141+EXPORT_SYMBOL(grsec_enable_randsrc);
12142+#endif
12143+#ifdef CONFIG_GRKERNSEC_RANDRPC
12144+EXPORT_SYMBOL(grsec_enable_randrpc);
12145+#endif
12146+
12147+EXPORT_SYMBOL(gr_cap_rtnetlink);
12148+
12149+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
12150+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
12151+
12152+EXPORT_SYMBOL(gr_search_udp_recvmsg);
12153+EXPORT_SYMBOL(gr_search_udp_sendmsg);
12154+
12155+#ifdef CONFIG_UNIX_MODULE
12156+EXPORT_SYMBOL(gr_acl_handle_unix);
12157+EXPORT_SYMBOL(gr_acl_handle_mknod);
12158+EXPORT_SYMBOL(gr_handle_chroot_unix);
12159+EXPORT_SYMBOL(gr_handle_create);
12160+#endif
12161+
12162 #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
12163 #include <net/iw_handler.h>
12164 EXPORT_SYMBOL(wireless_send_event);
12165diff -urN linux-2.4.22/net/socket.c linux-2.4.22/net/socket.c
12166--- linux-2.4.22/net/socket.c 2003-09-01 22:19:08.000000000 -0400
12167+++ linux-2.4.22/net/socket.c 2003-09-02 19:29:42.000000000 -0400
12168@@ -85,6 +85,18 @@
12169 #include <net/scm.h>
12170 #include <linux/netfilter.h>
12171
12172+extern void gr_attach_curr_ip(const struct sock *sk);
12173+extern int gr_handle_sock_all(const int family, const int type,
12174+ const int protocol);
12175+extern int gr_handle_sock_server(const struct sockaddr *sck);
12176+extern int gr_handle_sock_client(const struct sockaddr *sck);
12177+extern int gr_search_connect(const struct socket * sock,
12178+ const struct sockaddr_in * addr);
12179+extern int gr_search_bind(const struct socket * sock,
12180+ const struct sockaddr_in * addr);
12181+extern int gr_search_socket(const int domain, const int type,
12182+ const int protocol);
12183+
12184 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
12185 static ssize_t sock_read(struct file *file, char *buf,
12186 size_t size, loff_t *ppos);
12187@@ -699,6 +711,7 @@
12188
12189 int sock_close(struct inode *inode, struct file *filp)
12190 {
12191+ struct socket *sock;
12192 /*
12193 * It was possible the inode is NULL we were
12194 * closing an unfinished socket.
12195@@ -709,8 +722,21 @@
12196 printk(KERN_DEBUG "sock_close: NULL inode\n");
12197 return 0;
12198 }
12199+ sock = socki_lookup(inode);
12200+
12201 sock_fasync(-1, filp, 0);
12202+
12203+#ifdef CONFIG_GRKERNSEC
12204+ if (unlikely(current->used_accept && sock->sk &&
12205+ (sock->sk->protocol == IPPROTO_TCP) &&
12206+ (sock->sk->daddr == current->curr_ip))) {
12207+ current->used_accept = 0;
12208+ current->curr_ip = 0;
12209+ }
12210+#endif
12211+
12212 sock_release(socki_lookup(inode));
12213+
12214 return 0;
12215 }
12216
12217@@ -903,6 +929,16 @@
12218 int retval;
12219 struct socket *sock;
12220
12221+ if(!gr_search_socket(family, type, protocol)) {
12222+ retval = -EACCES;
12223+ goto out;
12224+ }
12225+
12226+ if (gr_handle_sock_all(family, type, protocol)) {
12227+ retval = -EACCES;
12228+ goto out;
12229+ }
12230+
12231 retval = sock_create(family, type, protocol, &sock);
12232 if (retval < 0)
12233 goto out;
12234@@ -998,12 +1034,26 @@
12235 {
12236 struct socket *sock;
12237 char address[MAX_SOCK_ADDR];
12238+ struct sockaddr * sck;
12239 int err;
12240
12241 if((sock = sockfd_lookup(fd,&err))!=NULL)
12242 {
12243- if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
12244+ if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) {
12245+ sck = (struct sockaddr *) address;
12246+
12247+ if(!gr_search_bind(sock, (struct sockaddr_in *) sck)) {
12248+ sockfd_put(sock);
12249+ return -EACCES;
12250+ }
12251+
12252+ if (gr_handle_sock_server(sck)) {
12253+ sockfd_put(sock);
12254+ return -EACCES;
12255+ }
12256+
12257 err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
12258+ }
12259 sockfd_put(sock);
12260 }
12261 return err;
12262@@ -1079,6 +1129,8 @@
12263 if ((err = sock_map_fd(newsock)) < 0)
12264 goto out_release;
12265
12266+ gr_attach_curr_ip(newsock->sk);
12267+
12268 out_put:
12269 sockfd_put(sock);
12270 out:
12271@@ -1106,6 +1158,7 @@
12272 {
12273 struct socket *sock;
12274 char address[MAX_SOCK_ADDR];
12275+ struct sockaddr * sck;
12276 int err;
12277
12278 sock = sockfd_lookup(fd, &err);
12279@@ -1114,6 +1167,24 @@
12280 err = move_addr_to_kernel(uservaddr, addrlen, address);
12281 if (err < 0)
12282 goto out_put;
12283+
12284+ sck = (struct sockaddr *) address;
12285+
12286+ if (!gr_search_connect(sock, (struct sockaddr_in *) sck)) {
12287+ err = -EACCES;
12288+ goto out_put;
12289+ }
12290+
12291+ if (gr_handle_sock_client(sck)) {
12292+ err = -EACCES;
12293+ goto out_put;
12294+ }
12295+
12296+#ifdef CONFIG_GRKERNSEC
12297+ if (sock->sk->protocol == IPPROTO_TCP)
12298+ current->used_connect = 1;
12299+#endif
12300+
12301 err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen,
12302 sock->file->f_flags);
12303 out_put:
12304@@ -1333,6 +1404,14 @@
12305 err=sock->ops->shutdown(sock, how);
12306 sockfd_put(sock);
12307 }
12308+
12309+#ifdef CONFIG_GRKERNSEC
12310+ if (likely(!err && current->used_accept)) {
12311+ current->used_accept = 0;
12312+ current->curr_ip = 0;
12313+ }
12314+#endif
12315+
12316 return err;
12317 }
12318
12319diff -urN linux-2.4.22/net/sunrpc/xprt.c linux-2.4.22/net/sunrpc/xprt.c
12320--- linux-2.4.22/net/sunrpc/xprt.c 2003-09-01 22:19:11.000000000 -0400
12321+++ linux-2.4.22/net/sunrpc/xprt.c 2003-09-02 19:29:42.000000000 -0400
12322@@ -59,6 +59,7 @@
12323 #include <linux/unistd.h>
12324 #include <linux/sunrpc/clnt.h>
12325 #include <linux/file.h>
12326+#include <linux/grsecurity.h>
12327
12328 #include <net/sock.h>
12329 #include <net/checksum.h>
12330@@ -1290,6 +1291,12 @@
12331 }
12332 ret = xid++;
12333 spin_unlock(&xid_lock);
12334+
12335+#ifdef CONFIG_GRKERNSEC_RANDRPC
12336+ if (grsec_enable_randrpc)
12337+ ret = (u32) get_random_long();
12338+#endif
12339+
12340 return ret;
12341 }
12342
12343diff -urN linux-2.4.22/net/unix/af_unix.c linux-2.4.22/net/unix/af_unix.c
12344--- linux-2.4.22/net/unix/af_unix.c 2003-09-01 22:19:08.000000000 -0400
12345+++ linux-2.4.22/net/unix/af_unix.c 2003-09-02 19:29:42.000000000 -0400
12346@@ -109,6 +109,7 @@
12347 #include <linux/poll.h>
12348 #include <linux/smp_lock.h>
12349 #include <linux/rtnetlink.h>
12350+#include <linux/grsecurity.h>
12351
12352 #include <asm/checksum.h>
12353
12354@@ -599,6 +600,11 @@
12355 if (err)
12356 goto put_fail;
12357
12358+ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
12359+ err = -EACCES;
12360+ goto put_fail;
12361+ }
12362+
12363 err = -ECONNREFUSED;
12364 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
12365 goto put_fail;
12366@@ -622,6 +628,13 @@
12367 if (u) {
12368 struct dentry *dentry;
12369 dentry = u->protinfo.af_unix.dentry;
12370+
12371+ if (!gr_handle_chroot_unix(u->peercred.pid)) {
12372+ err = -EPERM;
12373+ sock_put(u);
12374+ goto fail;
12375+ }
12376+
12377 if (dentry)
12378 UPDATE_ATIME(dentry->d_inode);
12379 } else
12380@@ -720,9 +733,19 @@
12381 * All right, let's create it.
12382 */
12383 mode = S_IFSOCK | (sock->inode->i_mode & ~current->fs->umask);
12384+
12385+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
12386+ err = -EACCES;
12387+ goto out_mknod_dput;
12388+ }
12389+
12390 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
12391+
12392 if (err)
12393 goto out_mknod_dput;
12394+
12395+ gr_handle_create(dentry, nd.mnt);
12396+
12397 up(&nd.dentry->d_inode->i_sem);
12398 dput(nd.dentry);
12399 nd.dentry = dentry;
12400@@ -740,6 +763,10 @@
12401 goto out_unlock;
12402 }
12403
12404+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
12405+ sk->peercred.pid = current->pid;
12406+#endif
12407+
12408 list = &unix_socket_table[addr->hash];
12409 } else {
12410 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
12411@@ -866,6 +893,9 @@
12412 int st;
12413 int err;
12414 long timeo;
12415+#ifdef CONFIG_GRKERNSEC
12416+ struct task_struct *p, **htable;
12417+#endif
12418
12419 err = unix_mkname(sunaddr, addr_len, &hash);
12420 if (err < 0)
12421@@ -989,6 +1019,17 @@
12422 /* Set credentials */
12423 sk->peercred = other->peercred;
12424
12425+#ifdef CONFIG_GRKERNSEC
12426+ read_lock(&tasklist_lock);
12427+ htable = &pidhash[pid_hashfn(other->peercred.pid)];
12428+ for (p = *htable; p && p->pid != other->peercred.pid; p = p->pidhash_next);
12429+ if (p) {
12430+ p->curr_ip = current->curr_ip;
12431+ p->used_accept = 1;
12432+ }
12433+ read_unlock(&tasklist_lock);
12434+#endif
12435+
12436 sock_hold(newsk);
12437 unix_peer(sk)=newsk;
12438 sock->state=SS_CONNECTED;
This page took 1.676126 seconds and 4 git commands to generate.