Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Smack: Simplified Mandatory Access Control Kernel

Smack is the Simplified Mandatory Access Control Kernel.

Smack implements mandatory access control (MAC) using labels
attached to tasks and data containers, including files, SVIPC,
and other tasks. Smack is a kernel based scheme that requires
an absolute minimum of application support and a very small
amount of configuration data.

Smack uses extended attributes and
provides a set of general mount options, borrowing technics used
elsewhere. Smack uses netlabel for CIPSO labeling. Smack provides
a pseudo-filesystem smackfs that is used for manipulation of
system Smack attributes.

The patch, patches for ls and sshd, a README, a startup script,
and x86 binaries for ls and sshd are also available on

http://www.schaufler-ca.com

Development has been done using Fedora Core 7 in a virtual machine
environment and on an old Sony laptop.

Smack provides mandatory access controls based on the label attached
to a task and the label attached to the object it is attempting to
access. Smack labels are deliberately short (1-23 characters) text
strings. Single character labels using special characters are reserved
for system use. The only operation applied to Smack labels is equality
comparison. No wildcards or expressions, regular or otherwise, are
used. Smack labels are composed of printable characters and may not
include "/".

A file always gets the Smack label of the task that created it.

Smack defines and uses these labels:

"*" - pronounced "star"
"_" - pronounced "floor"
"^" - pronounced "hat"
"?" - pronounced "huh"

The access rules enforced by Smack are, in order:

1. Any access requested by a task labeled "*" is denied.
2. A read or execute access requested by a task labeled "^"
is permitted.
3. A read or execute access requested on an object labeled "_"
is permitted.
4. Any access requested on an object labeled "*" is permitted.
5. Any access requested by a task on an object with the same
label is permitted.
6. Any access requested that is explicitly defined in the loaded
rule set is permitted.
7. Any other access is denied.

Rules may be explicitly defined by writing subject,object,access
triples to /smack/load.

Smack rule sets can be easily defined that describe Bell&LaPadula
sensitivity, Biba integrity, and a variety of interesting
configurations. Smack rule sets can be modified on the fly to
accommodate changes in the operating environment or even the time
of day.

Some practical use cases:

Hierarchical levels. The less common of the two usual uses
for MLS systems is to define hierarchical levels, often
unclassified, confidential, secret, and so on. To set up smack
to support this, these rules could be defined:

C Unclass rx
S C rx
S Unclass rx
TS S rx
TS C rx
TS Unclass rx

A TS process can read S, C, and Unclass data, but cannot write it.
An S process can read C and Unclass. Note that specifying that
TS can read S and S can read C does not imply TS can read C, it
has to be explicitly stated.

Non-hierarchical categories. This is the more common of the
usual uses for an MLS system. Since the default rule is that a
subject cannot access an object with a different label no
access rules are required to implement compartmentalization.

A case that the Bell & LaPadula policy does not allow is demonstrated
with this Smack access rule:

A case that Bell&LaPadula does not allow that Smack does:

ESPN ABC r
ABC ESPN r

On my portable video device I have two applications, one that
shows ABC programming and the other ESPN programming. ESPN wants
to show me sport stories that show up as news, and ABC will
only provide minimal information about a sports story if ESPN
is covering it. Each side can look at the other's info, neither
can change the other. Neither can see what FOX is up to, which
is just as well all things considered.

Another case that I especially like:

SatData Guard w
Guard Publish w

A program running with the Guard label opens a UDP socket and
accepts messages sent by a program running with a SatData label.
The Guard program inspects the message to ensure it is wholesome
and if it is sends it to a program running with the Publish label.
This program then puts the information passed in an appropriate
place. Note that the Guard program cannot write to a Publish
file system object because file system semanitic require read as
well as write.

The four cases (categories, levels, mutual read, guardbox) here
are all quite real, and problems I've been asked to solve over
the years. The first two are easy to do with traditonal MLS systems
while the last two you can't without invoking privilege, at least
for a while.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Cc: Joshua Brindle <method@manicmethod.com>
Cc: Paul Moore <paul.moore@hp.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Chris Wright <chrisw@sous-sol.org>
Cc: James Morris <jmorris@namei.org>
Cc: "Ahmed S. Darwish" <darwish.07@gmail.com>
Cc: Andrew G. Morgan <morgan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Casey Schaufler and committed by
Linus Torvalds
e114e473 eda61d32

+4611 -3
+493
Documentation/Smack.txt
··· 1 + 2 + 3 + "Good for you, you've decided to clean the elevator!" 4 + - The Elevator, from Dark Star 5 + 6 + Smack is the the Simplified Mandatory Access Control Kernel. 7 + Smack is a kernel based implementation of mandatory access 8 + control that includes simplicity in its primary design goals. 9 + 10 + Smack is not the only Mandatory Access Control scheme 11 + available for Linux. Those new to Mandatory Access Control 12 + are encouraged to compare Smack with the other mechanisms 13 + available to determine which is best suited to the problem 14 + at hand. 15 + 16 + Smack consists of three major components: 17 + - The kernel 18 + - A start-up script and a few modified applications 19 + - Configuration data 20 + 21 + The kernel component of Smack is implemented as a Linux 22 + Security Modules (LSM) module. It requires netlabel and 23 + works best with file systems that support extended attributes, 24 + although xattr support is not strictly required. 25 + It is safe to run a Smack kernel under a "vanilla" distribution. 26 + Smack kernels use the CIPSO IP option. Some network 27 + configurations are intolerant of IP options and can impede 28 + access to systems that use them as Smack does. 29 + 30 + The startup script etc-init.d-smack should be installed 31 + in /etc/init.d/smack and should be invoked early in the 32 + start-up process. On Fedora rc5.d/S02smack is recommended. 33 + This script ensures that certain devices have the correct 34 + Smack attributes and loads the Smack configuration if 35 + any is defined. This script invokes two programs that 36 + ensure configuration data is properly formatted. These 37 + programs are /usr/sbin/smackload and /usr/sin/smackcipso. 38 + The system will run just fine without these programs, 39 + but it will be difficult to set access rules properly. 40 + 41 + A version of "ls" that provides a "-M" option to display 42 + Smack labels on long listing is available. 43 + 44 + A hacked version of sshd that allows network logins by users 45 + with specific Smack labels is available. This version does 46 + not work for scp. You must set the /etc/ssh/sshd_config 47 + line: 48 + UsePrivilegeSeparation no 49 + 50 + The format of /etc/smack/usr is: 51 + 52 + username smack 53 + 54 + In keeping with the intent of Smack, configuration data is 55 + minimal and not strictly required. The most important 56 + configuration step is mounting the smackfs pseudo filesystem. 57 + 58 + Add this line to /etc/fstab: 59 + 60 + smackfs /smack smackfs smackfsdef=* 0 0 61 + 62 + and create the /smack directory for mounting. 63 + 64 + Smack uses extended attributes (xattrs) to store file labels. 65 + The command to set a Smack label on a file is: 66 + 67 + # attr -S -s SMACK64 -V "value" path 68 + 69 + NOTE: Smack labels are limited to 23 characters. The attr command 70 + does not enforce this restriction and can be used to set 71 + invalid Smack labels on files. 72 + 73 + If you don't do anything special all users will get the floor ("_") 74 + label when they log in. If you do want to log in via the hacked ssh 75 + at other labels use the attr command to set the smack value on the 76 + home directory and it's contents. 77 + 78 + You can add access rules in /etc/smack/accesses. They take the form: 79 + 80 + subjectlabel objectlabel access 81 + 82 + access is a combination of the letters rwxa which specify the 83 + kind of access permitted a subject with subjectlabel on an 84 + object with objectlabel. If there is no rule no access is allowed. 85 + 86 + A process can see the smack label it is running with by 87 + reading /proc/self/attr/current. A privileged process can 88 + set the process smack by writing there. 89 + 90 + Look for additional programs on http://schaufler-ca.com 91 + 92 + From the Smack Whitepaper: 93 + 94 + The Simplified Mandatory Access Control Kernel 95 + 96 + Casey Schaufler 97 + casey@schaufler-ca.com 98 + 99 + Mandatory Access Control 100 + 101 + Computer systems employ a variety of schemes to constrain how information is 102 + shared among the people and services using the machine. Some of these schemes 103 + allow the program or user to decide what other programs or users are allowed 104 + access to pieces of data. These schemes are called discretionary access 105 + control mechanisms because the access control is specified at the discretion 106 + of the user. Other schemes do not leave the decision regarding what a user or 107 + program can access up to users or programs. These schemes are called mandatory 108 + access control mechanisms because you don't have a choice regarding the users 109 + or programs that have access to pieces of data. 110 + 111 + Bell & LaPadula 112 + 113 + From the middle of the 1980's until the turn of the century Mandatory Access 114 + Control (MAC) was very closely associated with the Bell & LaPadula security 115 + model, a mathematical description of the United States Department of Defense 116 + policy for marking paper documents. MAC in this form enjoyed a following 117 + within the Capital Beltway and Scandinavian supercomputer centers but was 118 + often sited as failing to address general needs. 119 + 120 + Domain Type Enforcement 121 + 122 + Around the turn of the century Domain Type Enforcement (DTE) became popular. 123 + This scheme organizes users, programs, and data into domains that are 124 + protected from each other. This scheme has been widely deployed as a component 125 + of popular Linux distributions. The administrative overhead required to 126 + maintain this scheme and the detailed understanding of the whole system 127 + necessary to provide a secure domain mapping leads to the scheme being 128 + disabled or used in limited ways in the majority of cases. 129 + 130 + Smack 131 + 132 + Smack is a Mandatory Access Control mechanism designed to provide useful MAC 133 + while avoiding the pitfalls of its predecessors. The limitations of Bell & 134 + LaPadula are addressed by providing a scheme whereby access can be controlled 135 + according to the requirements of the system and its purpose rather than those 136 + imposed by an arcane government policy. The complexity of Domain Type 137 + Enforcement and avoided by defining access controls in terms of the access 138 + modes already in use. 139 + 140 + Smack Terminology 141 + 142 + The jargon used to talk about Smack will be familiar to those who have dealt 143 + with other MAC systems and shouldn't be too difficult for the uninitiated to 144 + pick up. There are four terms that are used in a specific way and that are 145 + especially important: 146 + 147 + Subject: A subject is an active entity on the computer system. 148 + On Smack a subject is a task, which is in turn the basic unit 149 + of execution. 150 + 151 + Object: An object is a passive entity on the computer system. 152 + On Smack files of all types, IPC, and tasks can be objects. 153 + 154 + Access: Any attempt by a subject to put information into or get 155 + information from an object is an access. 156 + 157 + Label: Data that identifies the Mandatory Access Control 158 + characteristics of a subject or an object. 159 + 160 + These definitions are consistent with the traditional use in the security 161 + community. There are also some terms from Linux that are likely to crop up: 162 + 163 + Capability: A task that possesses a capability has permission to 164 + violate an aspect of the system security policy, as identified by 165 + the specific capability. A task that possesses one or more 166 + capabilities is a privileged task, whereas a task with no 167 + capabilities is an unprivileged task. 168 + 169 + Privilege: A task that is allowed to violate the system security 170 + policy is said to have privilege. As of this writing a task can 171 + have privilege either by possessing capabilities or by having an 172 + effective user of root. 173 + 174 + Smack Basics 175 + 176 + Smack is an extension to a Linux system. It enforces additional restrictions 177 + on what subjects can access which objects, based on the labels attached to 178 + each of the subject and the object. 179 + 180 + Labels 181 + 182 + Smack labels are ASCII character strings, one to twenty-three characters in 183 + length. Single character labels using special characters, that being anything 184 + other than a letter or digit, are reserved for use by the Smack development 185 + team. Smack labels are unstructured, case sensitive, and the only operation 186 + ever performed on them is comparison for equality. Smack labels cannot 187 + contain unprintable characters or the "/" (slash) character. 188 + 189 + There are some predefined labels: 190 + 191 + _ Pronounced "floor", a single underscore character. 192 + ^ Pronounced "hat", a single circumflex character. 193 + * Pronounced "star", a single asterisk character. 194 + ? Pronounced "huh", a single question mark character. 195 + 196 + Every task on a Smack system is assigned a label. System tasks, such as 197 + init(8) and systems daemons, are run with the floor ("_") label. User tasks 198 + are assigned labels according to the specification found in the 199 + /etc/smack/user configuration file. 200 + 201 + Access Rules 202 + 203 + Smack uses the traditional access modes of Linux. These modes are read, 204 + execute, write, and occasionally append. There are a few cases where the 205 + access mode may not be obvious. These include: 206 + 207 + Signals: A signal is a write operation from the subject task to 208 + the object task. 209 + Internet Domain IPC: Transmission of a packet is considered a 210 + write operation from the source task to the destination task. 211 + 212 + Smack restricts access based on the label attached to a subject and the label 213 + attached to the object it is trying to access. The rules enforced are, in 214 + order: 215 + 216 + 1. Any access requested by a task labeled "*" is denied. 217 + 2. A read or execute access requested by a task labeled "^" 218 + is permitted. 219 + 3. A read or execute access requested on an object labeled "_" 220 + is permitted. 221 + 4. Any access requested on an object labeled "*" is permitted. 222 + 5. Any access requested by a task on an object with the same 223 + label is permitted. 224 + 6. Any access requested that is explicitly defined in the loaded 225 + rule set is permitted. 226 + 7. Any other access is denied. 227 + 228 + Smack Access Rules 229 + 230 + With the isolation provided by Smack access separation is simple. There are 231 + many interesting cases where limited access by subjects to objects with 232 + different labels is desired. One example is the familiar spy model of 233 + sensitivity, where a scientist working on a highly classified project would be 234 + able to read documents of lower classifications and anything she writes will 235 + be "born" highly classified. To accommodate such schemes Smack includes a 236 + mechanism for specifying rules allowing access between labels. 237 + 238 + Access Rule Format 239 + 240 + The format of an access rule is: 241 + 242 + subject-label object-label access 243 + 244 + Where subject-label is the Smack label of the task, object-label is the Smack 245 + label of the thing being accessed, and access is a string specifying the sort 246 + of access allowed. The Smack labels are limited to 23 characters. The access 247 + specification is searched for letters that describe access modes: 248 + 249 + a: indicates that append access should be granted. 250 + r: indicates that read access should be granted. 251 + w: indicates that write access should be granted. 252 + x: indicates that execute access should be granted. 253 + 254 + Uppercase values for the specification letters are allowed as well. 255 + Access mode specifications can be in any order. Examples of acceptable rules 256 + are: 257 + 258 + TopSecret Secret rx 259 + Secret Unclass R 260 + Manager Game x 261 + User HR w 262 + New Old rRrRr 263 + Closed Off - 264 + 265 + Examples of unacceptable rules are: 266 + 267 + Top Secret Secret rx 268 + Ace Ace r 269 + Odd spells waxbeans 270 + 271 + Spaces are not allowed in labels. Since a subject always has access to files 272 + with the same label specifying a rule for that case is pointless. Only 273 + valid letters (rwxaRWXA) and the dash ('-') character are allowed in 274 + access specifications. The dash is a placeholder, so "a-r" is the same 275 + as "ar". A lone dash is used to specify that no access should be allowed. 276 + 277 + Applying Access Rules 278 + 279 + The developers of Linux rarely define new sorts of things, usually importing 280 + schemes and concepts from other systems. Most often, the other systems are 281 + variants of Unix. Unix has many endearing properties, but consistency of 282 + access control models is not one of them. Smack strives to treat accesses as 283 + uniformly as is sensible while keeping with the spirit of the underlying 284 + mechanism. 285 + 286 + File system objects including files, directories, named pipes, symbolic links, 287 + and devices require access permissions that closely match those used by mode 288 + bit access. To open a file for reading read access is required on the file. To 289 + search a directory requires execute access. Creating a file with write access 290 + requires both read and write access on the containing directory. Deleting a 291 + file requires read and write access to the file and to the containing 292 + directory. It is possible that a user may be able to see that a file exists 293 + but not any of its attributes by the circumstance of having read access to the 294 + containing directory but not to the differently labeled file. This is an 295 + artifact of the file name being data in the directory, not a part of the file. 296 + 297 + IPC objects, message queues, semaphore sets, and memory segments exist in flat 298 + namespaces and access requests are only required to match the object in 299 + question. 300 + 301 + Process objects reflect tasks on the system and the Smack label used to access 302 + them is the same Smack label that the task would use for its own access 303 + attempts. Sending a signal via the kill() system call is a write operation 304 + from the signaler to the recipient. Debugging a process requires both reading 305 + and writing. Creating a new task is an internal operation that results in two 306 + tasks with identical Smack labels and requires no access checks. 307 + 308 + Sockets are data structures attached to processes and sending a packet from 309 + one process to another requires that the sender have write access to the 310 + receiver. The receiver is not required to have read access to the sender. 311 + 312 + Setting Access Rules 313 + 314 + The configuration file /etc/smack/accesses contains the rules to be set at 315 + system startup. The contents are written to the special file /smack/load. 316 + Rules can be written to /smack/load at any time and take effect immediately. 317 + For any pair of subject and object labels there can be only one rule, with the 318 + most recently specified overriding any earlier specification. 319 + 320 + The program smackload is provided to ensure data is formatted 321 + properly when written to /smack/load. This program reads lines 322 + of the form 323 + 324 + subjectlabel objectlabel mode. 325 + 326 + Task Attribute 327 + 328 + The Smack label of a process can be read from /proc/<pid>/attr/current. A 329 + process can read its own Smack label from /proc/self/attr/current. A 330 + privileged process can change its own Smack label by writing to 331 + /proc/self/attr/current but not the label of another process. 332 + 333 + File Attribute 334 + 335 + The Smack label of a filesystem object is stored as an extended attribute 336 + named SMACK64 on the file. This attribute is in the security namespace. It can 337 + only be changed by a process with privilege. 338 + 339 + Privilege 340 + 341 + A process with CAP_MAC_OVERRIDE is privileged. 342 + 343 + Smack Networking 344 + 345 + As mentioned before, Smack enforces access control on network protocol 346 + transmissions. Every packet sent by a Smack process is tagged with its Smack 347 + label. This is done by adding a CIPSO tag to the header of the IP packet. Each 348 + packet received is expected to have a CIPSO tag that identifies the label and 349 + if it lacks such a tag the network ambient label is assumed. Before the packet 350 + is delivered a check is made to determine that a subject with the label on the 351 + packet has write access to the receiving process and if that is not the case 352 + the packet is dropped. 353 + 354 + CIPSO Configuration 355 + 356 + It is normally unnecessary to specify the CIPSO configuration. The default 357 + values used by the system handle all internal cases. Smack will compose CIPSO 358 + label values to match the Smack labels being used without administrative 359 + intervention. Unlabeled packets that come into the system will be given the 360 + ambient label. 361 + 362 + Smack requires configuration in the case where packets from a system that is 363 + not smack that speaks CIPSO may be encountered. Usually this will be a Trusted 364 + Solaris system, but there are other, less widely deployed systems out there. 365 + CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level, 366 + and a category set with each packet. The DOI is intended to identify a group 367 + of systems that use compatible labeling schemes, and the DOI specified on the 368 + smack system must match that of the remote system or packets will be 369 + discarded. The DOI is 3 by default. The value can be read from /smack/doi and 370 + can be changed by writing to /smack/doi. 371 + 372 + The label and category set are mapped to a Smack label as defined in 373 + /etc/smack/cipso. 374 + 375 + A Smack/CIPSO mapping has the form: 376 + 377 + smack level [category [category]*] 378 + 379 + Smack does not expect the level or category sets to be related in any 380 + particular way and does not assume or assign accesses based on them. Some 381 + examples of mappings: 382 + 383 + TopSecret 7 384 + TS:A,B 7 1 2 385 + SecBDE 5 2 4 6 386 + RAFTERS 7 12 26 387 + 388 + The ":" and "," characters are permitted in a Smack label but have no special 389 + meaning. 390 + 391 + The mapping of Smack labels to CIPSO values is defined by writing to 392 + /smack/cipso. Again, the format of data written to this special file 393 + is highly restrictive, so the program smackcipso is provided to 394 + ensure the writes are done properly. This program takes mappings 395 + on the standard input and sends them to /smack/cipso properly. 396 + 397 + In addition to explicit mappings Smack supports direct CIPSO mappings. One 398 + CIPSO level is used to indicate that the category set passed in the packet is 399 + in fact an encoding of the Smack label. The level used is 250 by default. The 400 + value can be read from /smack/direct and changed by writing to /smack/direct. 401 + 402 + Socket Attributes 403 + 404 + There are two attributes that are associated with sockets. These attributes 405 + can only be set by privileged tasks, but any task can read them for their own 406 + sockets. 407 + 408 + SMACK64IPIN: The Smack label of the task object. A privileged 409 + program that will enforce policy may set this to the star label. 410 + 411 + SMACK64IPOUT: The Smack label transmitted with outgoing packets. 412 + A privileged program may set this to match the label of another 413 + task with which it hopes to communicate. 414 + 415 + Writing Applications for Smack 416 + 417 + There are three sorts of applications that will run on a Smack system. How an 418 + application interacts with Smack will determine what it will have to do to 419 + work properly under Smack. 420 + 421 + Smack Ignorant Applications 422 + 423 + By far the majority of applications have no reason whatever to care about the 424 + unique properties of Smack. Since invoking a program has no impact on the 425 + Smack label associated with the process the only concern likely to arise is 426 + whether the process has execute access to the program. 427 + 428 + Smack Relevant Applications 429 + 430 + Some programs can be improved by teaching them about Smack, but do not make 431 + any security decisions themselves. The utility ls(1) is one example of such a 432 + program. 433 + 434 + Smack Enforcing Applications 435 + 436 + These are special programs that not only know about Smack, but participate in 437 + the enforcement of system policy. In most cases these are the programs that 438 + set up user sessions. There are also network services that provide information 439 + to processes running with various labels. 440 + 441 + File System Interfaces 442 + 443 + Smack maintains labels on file system objects using extended attributes. The 444 + Smack label of a file, directory, or other file system object can be obtained 445 + using getxattr(2). 446 + 447 + len = getxattr("/", "security.SMACK64", value, sizeof (value)); 448 + 449 + will put the Smack label of the root directory into value. A privileged 450 + process can set the Smack label of a file system object with setxattr(2). 451 + 452 + len = strlen("Rubble"); 453 + rc = setxattr("/foo", "security.SMACK64", "Rubble", len, 0); 454 + 455 + will set the Smack label of /foo to "Rubble" if the program has appropriate 456 + privilege. 457 + 458 + Socket Interfaces 459 + 460 + The socket attributes can be read using fgetxattr(2). 461 + 462 + A privileged process can set the Smack label of outgoing packets with 463 + fsetxattr(2). 464 + 465 + len = strlen("Rubble"); 466 + rc = fsetxattr(fd, "security.SMACK64IPOUT", "Rubble", len, 0); 467 + 468 + will set the Smack label "Rubble" on packets going out from the socket if the 469 + program has appropriate privilege. 470 + 471 + rc = fsetxattr(fd, "security.SMACK64IPIN, "*", strlen("*"), 0); 472 + 473 + will set the Smack label "*" as the object label against which incoming 474 + packets will be checked if the program has appropriate privilege. 475 + 476 + Administration 477 + 478 + Smack supports some mount options: 479 + 480 + smackfsdef=label: specifies the label to give files that lack 481 + the Smack label extended attribute. 482 + 483 + smackfsroot=label: specifies the label to assign the root of the 484 + file system if it lacks the Smack extended attribute. 485 + 486 + smackfshat=label: specifies a label that must have read access to 487 + all labels set on the filesystem. Not yet enforced. 488 + 489 + smackfsfloor=label: specifies a label to which all labels set on the 490 + filesystem must have read access. Not yet enforced. 491 + 492 + These mount options apply to all file system types. 493 +
+23 -3
include/linux/capability.h
··· 315 315 316 316 #define CAP_SETFCAP 31 317 317 318 - #define CAP_LAST_CAP CAP_SETFCAP 318 + /* Override MAC access. 319 + The base kernel enforces no MAC policy. 320 + An LSM may enforce a MAC policy, and if it does and it chooses 321 + to implement capability based overrides of that policy, this is 322 + the capability it should use to do so. */ 323 + 324 + #define CAP_MAC_OVERRIDE 32 325 + 326 + /* Allow MAC configuration or state changes. 327 + The base kernel requires no MAC configuration. 328 + An LSM may enforce a MAC policy, and if it does and it chooses 329 + to implement capability based checks on modifications to that 330 + policy or the data required to maintain it, this is the 331 + capability it should use to do so. */ 332 + 333 + #define CAP_MAC_ADMIN 33 334 + 335 + #define CAP_LAST_CAP CAP_MAC_ADMIN 319 336 320 337 #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) 321 338 ··· 358 341 | CAP_TO_MASK(CAP_FOWNER) \ 359 342 | CAP_TO_MASK(CAP_FSETID)) 360 343 344 + # define CAP_FS_MASK_B1 (CAP_TO_MASK(CAP_MAC_OVERRIDE)) 345 + 361 346 #if _LINUX_CAPABILITY_U32S != 2 362 347 # error Fix up hand-coded capability macro initializers 363 348 #else /* HAND-CODED capability initializers */ ··· 367 348 # define CAP_EMPTY_SET {{ 0, 0 }} 368 349 # define CAP_FULL_SET {{ ~0, ~0 }} 369 350 # define CAP_INIT_EFF_SET {{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }} 370 - # define CAP_FS_SET {{ CAP_FS_MASK_B0, 0 }} 371 - # define CAP_NFSD_SET {{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), 0 }} 351 + # define CAP_FS_SET {{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } } 352 + # define CAP_NFSD_SET {{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ 353 + CAP_FS_MASK_B1 } } 372 354 373 355 #endif /* _LINUX_CAPABILITY_U32S != 2 */ 374 356
+1
security/Kconfig
··· 105 105 If you are unsure how to answer this question, answer N. 106 106 107 107 source security/selinux/Kconfig 108 + source security/smack/Kconfig 108 109 109 110 endmenu 110 111
+2
security/Makefile
··· 4 4 5 5 obj-$(CONFIG_KEYS) += keys/ 6 6 subdir-$(CONFIG_SECURITY_SELINUX) += selinux 7 + subdir-$(CONFIG_SECURITY_SMACK) += smack 7 8 8 9 # if we don't select a security model, use the default capabilities 9 10 ifneq ($(CONFIG_SECURITY),y) ··· 15 14 obj-$(CONFIG_SECURITY) += security.o dummy.o inode.o 16 15 # Must precede capability.o in order to stack properly. 17 16 obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o 17 + obj-$(CONFIG_SECURITY_SMACK) += commoncap.o smack/built-in.o 18 18 obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o 19 19 obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o
+10
security/smack/Kconfig
··· 1 + config SECURITY_SMACK 2 + bool "Simplified Mandatory Access Control Kernel Support" 3 + depends on NETLABEL && SECURITY_NETWORK 4 + default n 5 + help 6 + This selects the Simplified Mandatory Access Control Kernel. 7 + Smack is useful for sensitivity, integrity, and a variety 8 + of other mandatory security schemes. 9 + If you are unsure how to answer this question, answer N. 10 +
+7
security/smack/Makefile
··· 1 + # 2 + # Makefile for the SMACK LSM 3 + # 4 + 5 + obj-$(CONFIG_SECURITY_SMACK) := smack.o 6 + 7 + smack-y := smack_lsm.o smack_access.o smackfs.o
+220
security/smack/smack.h
··· 1 + /* 2 + * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation, version 2. 7 + * 8 + * Author: 9 + * Casey Schaufler <casey@schaufler-ca.com> 10 + * 11 + */ 12 + 13 + #ifndef _SECURITY_SMACK_H 14 + #define _SECURITY_SMACK_H 15 + 16 + #include <linux/capability.h> 17 + #include <linux/spinlock.h> 18 + #include <net/netlabel.h> 19 + 20 + /* 21 + * Why 23? CIPSO is constrained to 30, so a 32 byte buffer is 22 + * bigger than can be used, and 24 is the next lower multiple 23 + * of 8, and there are too many issues if there isn't space set 24 + * aside for the terminating null byte. 25 + */ 26 + #define SMK_MAXLEN 23 27 + #define SMK_LABELLEN (SMK_MAXLEN+1) 28 + 29 + /* 30 + * How many kinds of access are there? 31 + * Here's your answer. 32 + */ 33 + #define SMK_ACCESSDASH '-' 34 + #define SMK_ACCESSLOW "rwxa" 35 + #define SMK_ACCESSKINDS (sizeof(SMK_ACCESSLOW) - 1) 36 + 37 + struct superblock_smack { 38 + char *smk_root; 39 + char *smk_floor; 40 + char *smk_hat; 41 + char *smk_default; 42 + int smk_initialized; 43 + spinlock_t smk_sblock; /* for initialization */ 44 + }; 45 + 46 + struct socket_smack { 47 + char *smk_out; /* outbound label */ 48 + char *smk_in; /* inbound label */ 49 + char smk_packet[SMK_LABELLEN]; /* TCP peer label */ 50 + }; 51 + 52 + /* 53 + * Inode smack data 54 + */ 55 + struct inode_smack { 56 + char *smk_inode; /* label of the fso */ 57 + struct mutex smk_lock; /* initialization lock */ 58 + int smk_flags; /* smack inode flags */ 59 + }; 60 + 61 + #define SMK_INODE_INSTANT 0x01 /* inode is instantiated */ 62 + 63 + /* 64 + * A label access rule. 65 + */ 66 + struct smack_rule { 67 + char *smk_subject; 68 + char *smk_object; 69 + int smk_access; 70 + }; 71 + 72 + /* 73 + * An entry in the table of permitted label accesses. 74 + */ 75 + struct smk_list_entry { 76 + struct smk_list_entry *smk_next; 77 + struct smack_rule smk_rule; 78 + }; 79 + 80 + /* 81 + * An entry in the table mapping smack values to 82 + * CIPSO level/category-set values. 83 + */ 84 + struct smack_cipso { 85 + int smk_level; 86 + char smk_catset[SMK_LABELLEN]; 87 + }; 88 + 89 + /* 90 + * This is the repository for labels seen so that it is 91 + * not necessary to keep allocating tiny chuncks of memory 92 + * and so that they can be shared. 93 + * 94 + * Labels are never modified in place. Anytime a label 95 + * is imported (e.g. xattrset on a file) the list is checked 96 + * for it and it is added if it doesn't exist. The address 97 + * is passed out in either case. Entries are added, but 98 + * never deleted. 99 + * 100 + * Since labels are hanging around anyway it doesn't 101 + * hurt to maintain a secid for those awkward situations 102 + * where kernel components that ought to use LSM independent 103 + * interfaces don't. The secid should go away when all of 104 + * these components have been repaired. 105 + * 106 + * If there is a cipso value associated with the label it 107 + * gets stored here, too. This will most likely be rare as 108 + * the cipso direct mapping in used internally. 109 + */ 110 + struct smack_known { 111 + struct smack_known *smk_next; 112 + char smk_known[SMK_LABELLEN]; 113 + u32 smk_secid; 114 + struct smack_cipso *smk_cipso; 115 + spinlock_t smk_cipsolock; /* for changing cipso map */ 116 + }; 117 + 118 + /* 119 + * Mount options 120 + */ 121 + #define SMK_FSDEFAULT "smackfsdef=" 122 + #define SMK_FSFLOOR "smackfsfloor=" 123 + #define SMK_FSHAT "smackfshat=" 124 + #define SMK_FSROOT "smackfsroot=" 125 + 126 + /* 127 + * xattr names 128 + */ 129 + #define XATTR_SMACK_SUFFIX "SMACK64" 130 + #define XATTR_SMACK_IPIN "SMACK64IPIN" 131 + #define XATTR_SMACK_IPOUT "SMACK64IPOUT" 132 + #define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX 133 + #define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN 134 + #define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT 135 + 136 + /* 137 + * smackfs macic number 138 + */ 139 + #define SMACK_MAGIC 0x43415d53 /* "SMAC" */ 140 + 141 + /* 142 + * A limit on the number of entries in the lists 143 + * makes some of the list administration easier. 144 + */ 145 + #define SMACK_LIST_MAX 10000 146 + 147 + /* 148 + * CIPSO defaults. 149 + */ 150 + #define SMACK_CIPSO_DOI_DEFAULT 3 /* Historical */ 151 + #define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */ 152 + #define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */ 153 + #define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */ 154 + #define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */ 155 + 156 + /* 157 + * Just to make the common cases easier to deal with 158 + */ 159 + #define MAY_ANY (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC) 160 + #define MAY_ANYREAD (MAY_READ | MAY_EXEC) 161 + #define MAY_ANYWRITE (MAY_WRITE | MAY_APPEND) 162 + #define MAY_READWRITE (MAY_READ | MAY_WRITE) 163 + #define MAY_NOT 0 164 + 165 + /* 166 + * These functions are in smack_lsm.c 167 + */ 168 + struct inode_smack *new_inode_smack(char *); 169 + 170 + /* 171 + * These functions are in smack_access.c 172 + */ 173 + int smk_access(char *, char *, int); 174 + int smk_curacc(char *, u32); 175 + int smack_to_cipso(const char *, struct smack_cipso *); 176 + void smack_from_cipso(u32, char *, char *); 177 + char *smack_from_secid(const u32); 178 + char *smk_import(const char *, int); 179 + struct smack_known *smk_import_entry(const char *, int); 180 + u32 smack_to_secid(const char *); 181 + 182 + /* 183 + * Shared data. 184 + */ 185 + extern int smack_cipso_direct; 186 + extern int smack_net_nltype; 187 + extern char *smack_net_ambient; 188 + 189 + extern struct smack_known *smack_known; 190 + extern struct smack_known smack_known_floor; 191 + extern struct smack_known smack_known_hat; 192 + extern struct smack_known smack_known_huh; 193 + extern struct smack_known smack_known_invalid; 194 + extern struct smack_known smack_known_star; 195 + extern struct smack_known smack_known_unset; 196 + 197 + extern struct smk_list_entry *smack_list; 198 + 199 + /* 200 + * Stricly for CIPSO level manipulation. 201 + * Set the category bit number in a smack label sized buffer. 202 + */ 203 + static inline void smack_catset_bit(int cat, char *catsetp) 204 + { 205 + if (cat > SMK_LABELLEN * 8) 206 + return; 207 + 208 + catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8); 209 + } 210 + 211 + /* 212 + * Present a pointer to the smack label in an inode blob. 213 + */ 214 + static inline char *smk_of_inode(const struct inode *isp) 215 + { 216 + struct inode_smack *sip = isp->i_security; 217 + return sip->smk_inode; 218 + } 219 + 220 + #endif /* _SECURITY_SMACK_H */
+356
security/smack/smack_access.c
··· 1 + /* 2 + * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation, version 2. 7 + * 8 + * Author: 9 + * Casey Schaufler <casey@schaufler-ca.com> 10 + * 11 + */ 12 + 13 + #include <linux/types.h> 14 + #include <linux/fs.h> 15 + #include <linux/sched.h> 16 + #include "smack.h" 17 + 18 + struct smack_known smack_known_unset = { 19 + .smk_next = NULL, 20 + .smk_known = "UNSET", 21 + .smk_secid = 1, 22 + .smk_cipso = NULL, 23 + }; 24 + 25 + struct smack_known smack_known_huh = { 26 + .smk_next = &smack_known_unset, 27 + .smk_known = "?", 28 + .smk_secid = 2, 29 + .smk_cipso = NULL, 30 + }; 31 + 32 + struct smack_known smack_known_hat = { 33 + .smk_next = &smack_known_huh, 34 + .smk_known = "^", 35 + .smk_secid = 3, 36 + .smk_cipso = NULL, 37 + }; 38 + 39 + struct smack_known smack_known_star = { 40 + .smk_next = &smack_known_hat, 41 + .smk_known = "*", 42 + .smk_secid = 4, 43 + .smk_cipso = NULL, 44 + }; 45 + 46 + struct smack_known smack_known_floor = { 47 + .smk_next = &smack_known_star, 48 + .smk_known = "_", 49 + .smk_secid = 5, 50 + .smk_cipso = NULL, 51 + }; 52 + 53 + struct smack_known smack_known_invalid = { 54 + .smk_next = &smack_known_floor, 55 + .smk_known = "", 56 + .smk_secid = 6, 57 + .smk_cipso = NULL, 58 + }; 59 + 60 + struct smack_known *smack_known = &smack_known_invalid; 61 + 62 + /* 63 + * The initial value needs to be bigger than any of the 64 + * known values above. 65 + */ 66 + static u32 smack_next_secid = 10; 67 + 68 + /** 69 + * smk_access - determine if a subject has a specific access to an object 70 + * @subject_label: a pointer to the subject's Smack label 71 + * @object_label: a pointer to the object's Smack label 72 + * @request: the access requested, in "MAY" format 73 + * 74 + * This function looks up the subject/object pair in the 75 + * access rule list and returns 0 if the access is permitted, 76 + * non zero otherwise. 77 + * 78 + * Even though Smack labels are usually shared on smack_list 79 + * labels that come in off the network can't be imported 80 + * and added to the list for locking reasons. 81 + * 82 + * Therefore, it is necessary to check the contents of the labels, 83 + * not just the pointer values. Of course, in most cases the labels 84 + * will be on the list, so checking the pointers may be a worthwhile 85 + * optimization. 86 + */ 87 + int smk_access(char *subject_label, char *object_label, int request) 88 + { 89 + u32 may = MAY_NOT; 90 + struct smk_list_entry *sp; 91 + struct smack_rule *srp; 92 + 93 + /* 94 + * Hardcoded comparisons. 95 + * 96 + * A star subject can't access any object. 97 + */ 98 + if (subject_label == smack_known_star.smk_known || 99 + strcmp(subject_label, smack_known_star.smk_known) == 0) 100 + return -EACCES; 101 + /* 102 + * A star object can be accessed by any subject. 103 + */ 104 + if (object_label == smack_known_star.smk_known || 105 + strcmp(object_label, smack_known_star.smk_known) == 0) 106 + return 0; 107 + /* 108 + * An object can be accessed in any way by a subject 109 + * with the same label. 110 + */ 111 + if (subject_label == object_label || 112 + strcmp(subject_label, object_label) == 0) 113 + return 0; 114 + /* 115 + * A hat subject can read any object. 116 + * A floor object can be read by any subject. 117 + */ 118 + if ((request & MAY_ANYREAD) == request) { 119 + if (object_label == smack_known_floor.smk_known || 120 + strcmp(object_label, smack_known_floor.smk_known) == 0) 121 + return 0; 122 + if (subject_label == smack_known_hat.smk_known || 123 + strcmp(subject_label, smack_known_hat.smk_known) == 0) 124 + return 0; 125 + } 126 + /* 127 + * Beyond here an explicit relationship is required. 128 + * If the requested access is contained in the available 129 + * access (e.g. read is included in readwrite) it's 130 + * good. 131 + */ 132 + for (sp = smack_list; sp != NULL; sp = sp->smk_next) { 133 + srp = &sp->smk_rule; 134 + 135 + if (srp->smk_subject == subject_label || 136 + strcmp(srp->smk_subject, subject_label) == 0) { 137 + if (srp->smk_object == object_label || 138 + strcmp(srp->smk_object, object_label) == 0) { 139 + may = srp->smk_access; 140 + break; 141 + } 142 + } 143 + } 144 + /* 145 + * This is a bit map operation. 146 + */ 147 + if ((request & may) == request) 148 + return 0; 149 + 150 + return -EACCES; 151 + } 152 + 153 + /** 154 + * smk_curacc - determine if current has a specific access to an object 155 + * @object_label: a pointer to the object's Smack label 156 + * @request: the access requested, in "MAY" format 157 + * 158 + * This function checks the current subject label/object label pair 159 + * in the access rule list and returns 0 if the access is permitted, 160 + * non zero otherwise. It allows that current my have the capability 161 + * to override the rules. 162 + */ 163 + int smk_curacc(char *obj_label, u32 mode) 164 + { 165 + int rc; 166 + 167 + rc = smk_access(current->security, obj_label, mode); 168 + if (rc == 0) 169 + return 0; 170 + 171 + if (capable(CAP_MAC_OVERRIDE)) 172 + return 0; 173 + 174 + return rc; 175 + } 176 + 177 + static DEFINE_MUTEX(smack_known_lock); 178 + 179 + /** 180 + * smk_import_entry - import a label, return the list entry 181 + * @string: a text string that might be a Smack label 182 + * @len: the maximum size, or zero if it is NULL terminated. 183 + * 184 + * Returns a pointer to the entry in the label list that 185 + * matches the passed string, adding it if necessary. 186 + */ 187 + struct smack_known *smk_import_entry(const char *string, int len) 188 + { 189 + struct smack_known *skp; 190 + char smack[SMK_LABELLEN]; 191 + int found; 192 + int i; 193 + 194 + if (len <= 0 || len > SMK_MAXLEN) 195 + len = SMK_MAXLEN; 196 + 197 + for (i = 0, found = 0; i < SMK_LABELLEN; i++) { 198 + if (found) 199 + smack[i] = '\0'; 200 + else if (i >= len || string[i] > '~' || string[i] <= ' ' || 201 + string[i] == '/') { 202 + smack[i] = '\0'; 203 + found = 1; 204 + } else 205 + smack[i] = string[i]; 206 + } 207 + 208 + if (smack[0] == '\0') 209 + return NULL; 210 + 211 + mutex_lock(&smack_known_lock); 212 + 213 + for (skp = smack_known; skp != NULL; skp = skp->smk_next) 214 + if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) 215 + break; 216 + 217 + if (skp == NULL) { 218 + skp = kzalloc(sizeof(struct smack_known), GFP_KERNEL); 219 + if (skp != NULL) { 220 + skp->smk_next = smack_known; 221 + strncpy(skp->smk_known, smack, SMK_MAXLEN); 222 + skp->smk_secid = smack_next_secid++; 223 + skp->smk_cipso = NULL; 224 + spin_lock_init(&skp->smk_cipsolock); 225 + /* 226 + * Make sure that the entry is actually 227 + * filled before putting it on the list. 228 + */ 229 + smp_mb(); 230 + smack_known = skp; 231 + } 232 + } 233 + 234 + mutex_unlock(&smack_known_lock); 235 + 236 + return skp; 237 + } 238 + 239 + /** 240 + * smk_import - import a smack label 241 + * @string: a text string that might be a Smack label 242 + * @len: the maximum size, or zero if it is NULL terminated. 243 + * 244 + * Returns a pointer to the label in the label list that 245 + * matches the passed string, adding it if necessary. 246 + */ 247 + char *smk_import(const char *string, int len) 248 + { 249 + struct smack_known *skp; 250 + 251 + skp = smk_import_entry(string, len); 252 + if (skp == NULL) 253 + return NULL; 254 + return skp->smk_known; 255 + } 256 + 257 + /** 258 + * smack_from_secid - find the Smack label associated with a secid 259 + * @secid: an integer that might be associated with a Smack label 260 + * 261 + * Returns a pointer to the appropraite Smack label if there is one, 262 + * otherwise a pointer to the invalid Smack label. 263 + */ 264 + char *smack_from_secid(const u32 secid) 265 + { 266 + struct smack_known *skp; 267 + 268 + for (skp = smack_known; skp != NULL; skp = skp->smk_next) 269 + if (skp->smk_secid == secid) 270 + return skp->smk_known; 271 + 272 + /* 273 + * If we got this far someone asked for the translation 274 + * of a secid that is not on the list. 275 + */ 276 + return smack_known_invalid.smk_known; 277 + } 278 + 279 + /** 280 + * smack_to_secid - find the secid associated with a Smack label 281 + * @smack: the Smack label 282 + * 283 + * Returns the appropriate secid if there is one, 284 + * otherwise 0 285 + */ 286 + u32 smack_to_secid(const char *smack) 287 + { 288 + struct smack_known *skp; 289 + 290 + for (skp = smack_known; skp != NULL; skp = skp->smk_next) 291 + if (strncmp(skp->smk_known, smack, SMK_MAXLEN) == 0) 292 + return skp->smk_secid; 293 + return 0; 294 + } 295 + 296 + /** 297 + * smack_from_cipso - find the Smack label associated with a CIPSO option 298 + * @level: Bell & LaPadula level from the network 299 + * @cp: Bell & LaPadula categories from the network 300 + * @result: where to put the Smack value 301 + * 302 + * This is a simple lookup in the label table. 303 + * 304 + * This is an odd duck as far as smack handling goes in that 305 + * it sends back a copy of the smack label rather than a pointer 306 + * to the master list. This is done because it is possible for 307 + * a foreign host to send a smack label that is new to this 308 + * machine and hence not on the list. That would not be an 309 + * issue except that adding an entry to the master list can't 310 + * be done at that point. 311 + */ 312 + void smack_from_cipso(u32 level, char *cp, char *result) 313 + { 314 + struct smack_known *kp; 315 + char *final = NULL; 316 + 317 + for (kp = smack_known; final == NULL && kp != NULL; kp = kp->smk_next) { 318 + if (kp->smk_cipso == NULL) 319 + continue; 320 + 321 + spin_lock_bh(&kp->smk_cipsolock); 322 + 323 + if (kp->smk_cipso->smk_level == level && 324 + memcmp(kp->smk_cipso->smk_catset, cp, SMK_LABELLEN) == 0) 325 + final = kp->smk_known; 326 + 327 + spin_unlock_bh(&kp->smk_cipsolock); 328 + } 329 + if (final == NULL) 330 + final = smack_known_huh.smk_known; 331 + strncpy(result, final, SMK_MAXLEN); 332 + return; 333 + } 334 + 335 + /** 336 + * smack_to_cipso - find the CIPSO option to go with a Smack label 337 + * @smack: a pointer to the smack label in question 338 + * @cp: where to put the result 339 + * 340 + * Returns zero if a value is available, non-zero otherwise. 341 + */ 342 + int smack_to_cipso(const char *smack, struct smack_cipso *cp) 343 + { 344 + struct smack_known *kp; 345 + 346 + for (kp = smack_known; kp != NULL; kp = kp->smk_next) 347 + if (kp->smk_known == smack || 348 + strcmp(kp->smk_known, smack) == 0) 349 + break; 350 + 351 + if (kp == NULL || kp->smk_cipso == NULL) 352 + return -ENOENT; 353 + 354 + memcpy(cp, kp->smk_cipso, sizeof(struct smack_cipso)); 355 + return 0; 356 + }
+2518
security/smack/smack_lsm.c
··· 1 + /* 2 + * Simplified MAC Kernel (smack) security module 3 + * 4 + * This file contains the smack hook function implementations. 5 + * 6 + * Author: 7 + * Casey Schaufler <casey@schaufler-ca.com> 8 + * 9 + * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 10 + * 11 + * This program is free software; you can redistribute it and/or modify 12 + * it under the terms of the GNU General Public License version 2, 13 + * as published by the Free Software Foundation. 14 + */ 15 + 16 + #include <linux/xattr.h> 17 + #include <linux/pagemap.h> 18 + #include <linux/mount.h> 19 + #include <linux/stat.h> 20 + #include <linux/ext2_fs.h> 21 + #include <linux/kd.h> 22 + #include <asm/ioctls.h> 23 + #include <linux/tcp.h> 24 + #include <linux/udp.h> 25 + #include <linux/mutex.h> 26 + #include <linux/pipe_fs_i.h> 27 + #include <net/netlabel.h> 28 + #include <net/cipso_ipv4.h> 29 + 30 + #include "smack.h" 31 + 32 + /* 33 + * I hope these are the hokeyist lines of code in the module. Casey. 34 + */ 35 + #define DEVPTS_SUPER_MAGIC 0x1cd1 36 + #define SOCKFS_MAGIC 0x534F434B 37 + #define TMPFS_MAGIC 0x01021994 38 + 39 + /** 40 + * smk_fetch - Fetch the smack label from a file. 41 + * @ip: a pointer to the inode 42 + * @dp: a pointer to the dentry 43 + * 44 + * Returns a pointer to the master list entry for the Smack label 45 + * or NULL if there was no label to fetch. 46 + */ 47 + static char *smk_fetch(struct inode *ip, struct dentry *dp) 48 + { 49 + int rc; 50 + char in[SMK_LABELLEN]; 51 + 52 + if (ip->i_op->getxattr == NULL) 53 + return NULL; 54 + 55 + rc = ip->i_op->getxattr(dp, XATTR_NAME_SMACK, in, SMK_LABELLEN); 56 + if (rc < 0) 57 + return NULL; 58 + 59 + return smk_import(in, rc); 60 + } 61 + 62 + /** 63 + * new_inode_smack - allocate an inode security blob 64 + * @smack: a pointer to the Smack label to use in the blob 65 + * 66 + * Returns the new blob or NULL if there's no memory available 67 + */ 68 + struct inode_smack *new_inode_smack(char *smack) 69 + { 70 + struct inode_smack *isp; 71 + 72 + isp = kzalloc(sizeof(struct inode_smack), GFP_KERNEL); 73 + if (isp == NULL) 74 + return NULL; 75 + 76 + isp->smk_inode = smack; 77 + isp->smk_flags = 0; 78 + mutex_init(&isp->smk_lock); 79 + 80 + return isp; 81 + } 82 + 83 + /* 84 + * LSM hooks. 85 + * We he, that is fun! 86 + */ 87 + 88 + /** 89 + * smack_ptrace - Smack approval on ptrace 90 + * @ptp: parent task pointer 91 + * @ctp: child task pointer 92 + * 93 + * Returns 0 if access is OK, an error code otherwise 94 + * 95 + * Do the capability checks, and require read and write. 96 + */ 97 + static int smack_ptrace(struct task_struct *ptp, struct task_struct *ctp) 98 + { 99 + int rc; 100 + 101 + rc = cap_ptrace(ptp, ctp); 102 + if (rc != 0) 103 + return rc; 104 + 105 + rc = smk_access(ptp->security, ctp->security, MAY_READWRITE); 106 + if (rc != 0 && __capable(ptp, CAP_MAC_OVERRIDE)) 107 + return 0; 108 + 109 + return rc; 110 + } 111 + 112 + /** 113 + * smack_syslog - Smack approval on syslog 114 + * @type: message type 115 + * 116 + * Require that the task has the floor label 117 + * 118 + * Returns 0 on success, error code otherwise. 119 + */ 120 + static int smack_syslog(int type) 121 + { 122 + int rc; 123 + char *sp = current->security; 124 + 125 + rc = cap_syslog(type); 126 + if (rc != 0) 127 + return rc; 128 + 129 + if (capable(CAP_MAC_OVERRIDE)) 130 + return 0; 131 + 132 + if (sp != smack_known_floor.smk_known) 133 + rc = -EACCES; 134 + 135 + return rc; 136 + } 137 + 138 + 139 + /* 140 + * Superblock Hooks. 141 + */ 142 + 143 + /** 144 + * smack_sb_alloc_security - allocate a superblock blob 145 + * @sb: the superblock getting the blob 146 + * 147 + * Returns 0 on success or -ENOMEM on error. 148 + */ 149 + static int smack_sb_alloc_security(struct super_block *sb) 150 + { 151 + struct superblock_smack *sbsp; 152 + 153 + sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL); 154 + 155 + if (sbsp == NULL) 156 + return -ENOMEM; 157 + 158 + sbsp->smk_root = smack_known_floor.smk_known; 159 + sbsp->smk_default = smack_known_floor.smk_known; 160 + sbsp->smk_floor = smack_known_floor.smk_known; 161 + sbsp->smk_hat = smack_known_hat.smk_known; 162 + sbsp->smk_initialized = 0; 163 + spin_lock_init(&sbsp->smk_sblock); 164 + 165 + sb->s_security = sbsp; 166 + 167 + return 0; 168 + } 169 + 170 + /** 171 + * smack_sb_free_security - free a superblock blob 172 + * @sb: the superblock getting the blob 173 + * 174 + */ 175 + static void smack_sb_free_security(struct super_block *sb) 176 + { 177 + kfree(sb->s_security); 178 + sb->s_security = NULL; 179 + } 180 + 181 + /** 182 + * smack_sb_copy_data - copy mount options data for processing 183 + * @type: file system type 184 + * @orig: where to start 185 + * @smackopts 186 + * 187 + * Returns 0 on success or -ENOMEM on error. 188 + * 189 + * Copy the Smack specific mount options out of the mount 190 + * options list. 191 + */ 192 + static int smack_sb_copy_data(struct file_system_type *type, void *orig, 193 + void *smackopts) 194 + { 195 + char *cp, *commap, *otheropts, *dp; 196 + 197 + /* Binary mount data: just copy */ 198 + if (type->fs_flags & FS_BINARY_MOUNTDATA) { 199 + copy_page(smackopts, orig); 200 + return 0; 201 + } 202 + 203 + otheropts = (char *)get_zeroed_page(GFP_KERNEL); 204 + if (otheropts == NULL) 205 + return -ENOMEM; 206 + 207 + for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) { 208 + if (strstr(cp, SMK_FSDEFAULT) == cp) 209 + dp = smackopts; 210 + else if (strstr(cp, SMK_FSFLOOR) == cp) 211 + dp = smackopts; 212 + else if (strstr(cp, SMK_FSHAT) == cp) 213 + dp = smackopts; 214 + else if (strstr(cp, SMK_FSROOT) == cp) 215 + dp = smackopts; 216 + else 217 + dp = otheropts; 218 + 219 + commap = strchr(cp, ','); 220 + if (commap != NULL) 221 + *commap = '\0'; 222 + 223 + if (*dp != '\0') 224 + strcat(dp, ","); 225 + strcat(dp, cp); 226 + } 227 + 228 + strcpy(orig, otheropts); 229 + free_page((unsigned long)otheropts); 230 + 231 + return 0; 232 + } 233 + 234 + /** 235 + * smack_sb_kern_mount - Smack specific mount processing 236 + * @sb: the file system superblock 237 + * @data: the smack mount options 238 + * 239 + * Returns 0 on success, an error code on failure 240 + */ 241 + static int smack_sb_kern_mount(struct super_block *sb, void *data) 242 + { 243 + struct dentry *root = sb->s_root; 244 + struct inode *inode = root->d_inode; 245 + struct superblock_smack *sp = sb->s_security; 246 + struct inode_smack *isp; 247 + char *op; 248 + char *commap; 249 + char *nsp; 250 + 251 + spin_lock(&sp->smk_sblock); 252 + if (sp->smk_initialized != 0) { 253 + spin_unlock(&sp->smk_sblock); 254 + return 0; 255 + } 256 + sp->smk_initialized = 1; 257 + spin_unlock(&sp->smk_sblock); 258 + 259 + for (op = data; op != NULL; op = commap) { 260 + commap = strchr(op, ','); 261 + if (commap != NULL) 262 + *commap++ = '\0'; 263 + 264 + if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { 265 + op += strlen(SMK_FSHAT); 266 + nsp = smk_import(op, 0); 267 + if (nsp != NULL) 268 + sp->smk_hat = nsp; 269 + } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { 270 + op += strlen(SMK_FSFLOOR); 271 + nsp = smk_import(op, 0); 272 + if (nsp != NULL) 273 + sp->smk_floor = nsp; 274 + } else if (strncmp(op, SMK_FSDEFAULT, 275 + strlen(SMK_FSDEFAULT)) == 0) { 276 + op += strlen(SMK_FSDEFAULT); 277 + nsp = smk_import(op, 0); 278 + if (nsp != NULL) 279 + sp->smk_default = nsp; 280 + } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { 281 + op += strlen(SMK_FSROOT); 282 + nsp = smk_import(op, 0); 283 + if (nsp != NULL) 284 + sp->smk_root = nsp; 285 + } 286 + } 287 + 288 + /* 289 + * Initialize the root inode. 290 + */ 291 + isp = inode->i_security; 292 + if (isp == NULL) 293 + inode->i_security = new_inode_smack(sp->smk_root); 294 + else 295 + isp->smk_inode = sp->smk_root; 296 + 297 + return 0; 298 + } 299 + 300 + /** 301 + * smack_sb_statfs - Smack check on statfs 302 + * @dentry: identifies the file system in question 303 + * 304 + * Returns 0 if current can read the floor of the filesystem, 305 + * and error code otherwise 306 + */ 307 + static int smack_sb_statfs(struct dentry *dentry) 308 + { 309 + struct superblock_smack *sbp = dentry->d_sb->s_security; 310 + 311 + return smk_curacc(sbp->smk_floor, MAY_READ); 312 + } 313 + 314 + /** 315 + * smack_sb_mount - Smack check for mounting 316 + * @dev_name: unused 317 + * @nd: mount point 318 + * @type: unused 319 + * @flags: unused 320 + * @data: unused 321 + * 322 + * Returns 0 if current can write the floor of the filesystem 323 + * being mounted on, an error code otherwise. 324 + */ 325 + static int smack_sb_mount(char *dev_name, struct nameidata *nd, 326 + char *type, unsigned long flags, void *data) 327 + { 328 + struct superblock_smack *sbp = nd->mnt->mnt_sb->s_security; 329 + 330 + return smk_curacc(sbp->smk_floor, MAY_WRITE); 331 + } 332 + 333 + /** 334 + * smack_sb_umount - Smack check for unmounting 335 + * @mnt: file system to unmount 336 + * @flags: unused 337 + * 338 + * Returns 0 if current can write the floor of the filesystem 339 + * being unmounted, an error code otherwise. 340 + */ 341 + static int smack_sb_umount(struct vfsmount *mnt, int flags) 342 + { 343 + struct superblock_smack *sbp; 344 + 345 + sbp = mnt->mnt_sb->s_security; 346 + 347 + return smk_curacc(sbp->smk_floor, MAY_WRITE); 348 + } 349 + 350 + /* 351 + * Inode hooks 352 + */ 353 + 354 + /** 355 + * smack_inode_alloc_security - allocate an inode blob 356 + * @inode - the inode in need of a blob 357 + * 358 + * Returns 0 if it gets a blob, -ENOMEM otherwise 359 + */ 360 + static int smack_inode_alloc_security(struct inode *inode) 361 + { 362 + inode->i_security = new_inode_smack(current->security); 363 + if (inode->i_security == NULL) 364 + return -ENOMEM; 365 + return 0; 366 + } 367 + 368 + /** 369 + * smack_inode_free_security - free an inode blob 370 + * @inode - the inode with a blob 371 + * 372 + * Clears the blob pointer in inode 373 + */ 374 + static void smack_inode_free_security(struct inode *inode) 375 + { 376 + kfree(inode->i_security); 377 + inode->i_security = NULL; 378 + } 379 + 380 + /** 381 + * smack_inode_init_security - copy out the smack from an inode 382 + * @inode: the inode 383 + * @dir: unused 384 + * @name: where to put the attribute name 385 + * @value: where to put the attribute value 386 + * @len: where to put the length of the attribute 387 + * 388 + * Returns 0 if it all works out, -ENOMEM if there's no memory 389 + */ 390 + static int smack_inode_init_security(struct inode *inode, struct inode *dir, 391 + char **name, void **value, size_t *len) 392 + { 393 + char *isp = smk_of_inode(inode); 394 + 395 + if (name) { 396 + *name = kstrdup(XATTR_SMACK_SUFFIX, GFP_KERNEL); 397 + if (*name == NULL) 398 + return -ENOMEM; 399 + } 400 + 401 + if (value) { 402 + *value = kstrdup(isp, GFP_KERNEL); 403 + if (*value == NULL) 404 + return -ENOMEM; 405 + } 406 + 407 + if (len) 408 + *len = strlen(isp) + 1; 409 + 410 + return 0; 411 + } 412 + 413 + /** 414 + * smack_inode_link - Smack check on link 415 + * @old_dentry: the existing object 416 + * @dir: unused 417 + * @new_dentry: the new object 418 + * 419 + * Returns 0 if access is permitted, an error code otherwise 420 + */ 421 + static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, 422 + struct dentry *new_dentry) 423 + { 424 + int rc; 425 + char *isp; 426 + 427 + isp = smk_of_inode(old_dentry->d_inode); 428 + rc = smk_curacc(isp, MAY_WRITE); 429 + 430 + if (rc == 0 && new_dentry->d_inode != NULL) { 431 + isp = smk_of_inode(new_dentry->d_inode); 432 + rc = smk_curacc(isp, MAY_WRITE); 433 + } 434 + 435 + return rc; 436 + } 437 + 438 + /** 439 + * smack_inode_unlink - Smack check on inode deletion 440 + * @dir: containing directory object 441 + * @dentry: file to unlink 442 + * 443 + * Returns 0 if current can write the containing directory 444 + * and the object, error code otherwise 445 + */ 446 + static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) 447 + { 448 + struct inode *ip = dentry->d_inode; 449 + int rc; 450 + 451 + /* 452 + * You need write access to the thing you're unlinking 453 + */ 454 + rc = smk_curacc(smk_of_inode(ip), MAY_WRITE); 455 + if (rc == 0) 456 + /* 457 + * You also need write access to the containing directory 458 + */ 459 + rc = smk_curacc(smk_of_inode(dir), MAY_WRITE); 460 + 461 + return rc; 462 + } 463 + 464 + /** 465 + * smack_inode_rmdir - Smack check on directory deletion 466 + * @dir: containing directory object 467 + * @dentry: directory to unlink 468 + * 469 + * Returns 0 if current can write the containing directory 470 + * and the directory, error code otherwise 471 + */ 472 + static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) 473 + { 474 + int rc; 475 + 476 + /* 477 + * You need write access to the thing you're removing 478 + */ 479 + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 480 + if (rc == 0) 481 + /* 482 + * You also need write access to the containing directory 483 + */ 484 + rc = smk_curacc(smk_of_inode(dir), MAY_WRITE); 485 + 486 + return rc; 487 + } 488 + 489 + /** 490 + * smack_inode_rename - Smack check on rename 491 + * @old_inode: the old directory 492 + * @old_dentry: unused 493 + * @new_inode: the new directory 494 + * @new_dentry: unused 495 + * 496 + * Read and write access is required on both the old and 497 + * new directories. 498 + * 499 + * Returns 0 if access is permitted, an error code otherwise 500 + */ 501 + static int smack_inode_rename(struct inode *old_inode, 502 + struct dentry *old_dentry, 503 + struct inode *new_inode, 504 + struct dentry *new_dentry) 505 + { 506 + int rc; 507 + char *isp; 508 + 509 + isp = smk_of_inode(old_dentry->d_inode); 510 + rc = smk_curacc(isp, MAY_READWRITE); 511 + 512 + if (rc == 0 && new_dentry->d_inode != NULL) { 513 + isp = smk_of_inode(new_dentry->d_inode); 514 + rc = smk_curacc(isp, MAY_READWRITE); 515 + } 516 + 517 + return rc; 518 + } 519 + 520 + /** 521 + * smack_inode_permission - Smack version of permission() 522 + * @inode: the inode in question 523 + * @mask: the access requested 524 + * @nd: unused 525 + * 526 + * This is the important Smack hook. 527 + * 528 + * Returns 0 if access is permitted, -EACCES otherwise 529 + */ 530 + static int smack_inode_permission(struct inode *inode, int mask, 531 + struct nameidata *nd) 532 + { 533 + /* 534 + * No permission to check. Existence test. Yup, it's there. 535 + */ 536 + if (mask == 0) 537 + return 0; 538 + 539 + return smk_curacc(smk_of_inode(inode), mask); 540 + } 541 + 542 + /** 543 + * smack_inode_setattr - Smack check for setting attributes 544 + * @dentry: the object 545 + * @iattr: for the force flag 546 + * 547 + * Returns 0 if access is permitted, an error code otherwise 548 + */ 549 + static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) 550 + { 551 + /* 552 + * Need to allow for clearing the setuid bit. 553 + */ 554 + if (iattr->ia_valid & ATTR_FORCE) 555 + return 0; 556 + 557 + return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 558 + } 559 + 560 + /** 561 + * smack_inode_getattr - Smack check for getting attributes 562 + * @mnt: unused 563 + * @dentry: the object 564 + * 565 + * Returns 0 if access is permitted, an error code otherwise 566 + */ 567 + static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 568 + { 569 + return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); 570 + } 571 + 572 + /** 573 + * smack_inode_setxattr - Smack check for setting xattrs 574 + * @dentry: the object 575 + * @name: name of the attribute 576 + * @value: unused 577 + * @size: unused 578 + * @flags: unused 579 + * 580 + * This protects the Smack attribute explicitly. 581 + * 582 + * Returns 0 if access is permitted, an error code otherwise 583 + */ 584 + static int smack_inode_setxattr(struct dentry *dentry, char *name, 585 + void *value, size_t size, int flags) 586 + { 587 + if (!capable(CAP_MAC_ADMIN)) { 588 + if (strcmp(name, XATTR_NAME_SMACK) == 0 || 589 + strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || 590 + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) 591 + return -EPERM; 592 + } 593 + 594 + return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 595 + } 596 + 597 + /** 598 + * smack_inode_post_setxattr - Apply the Smack update approved above 599 + * @dentry: object 600 + * @name: attribute name 601 + * @value: attribute value 602 + * @size: attribute size 603 + * @flags: unused 604 + * 605 + * Set the pointer in the inode blob to the entry found 606 + * in the master label list. 607 + */ 608 + static void smack_inode_post_setxattr(struct dentry *dentry, char *name, 609 + void *value, size_t size, int flags) 610 + { 611 + struct inode_smack *isp; 612 + char *nsp; 613 + 614 + /* 615 + * Not SMACK 616 + */ 617 + if (strcmp(name, XATTR_NAME_SMACK)) 618 + return; 619 + 620 + if (size >= SMK_LABELLEN) 621 + return; 622 + 623 + isp = dentry->d_inode->i_security; 624 + 625 + /* 626 + * No locking is done here. This is a pointer 627 + * assignment. 628 + */ 629 + nsp = smk_import(value, size); 630 + if (nsp != NULL) 631 + isp->smk_inode = nsp; 632 + else 633 + isp->smk_inode = smack_known_invalid.smk_known; 634 + 635 + return; 636 + } 637 + 638 + /* 639 + * smack_inode_getxattr - Smack check on getxattr 640 + * @dentry: the object 641 + * @name: unused 642 + * 643 + * Returns 0 if access is permitted, an error code otherwise 644 + */ 645 + static int smack_inode_getxattr(struct dentry *dentry, char *name) 646 + { 647 + return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); 648 + } 649 + 650 + /* 651 + * smack_inode_removexattr - Smack check on removexattr 652 + * @dentry: the object 653 + * @name: name of the attribute 654 + * 655 + * Removing the Smack attribute requires CAP_MAC_ADMIN 656 + * 657 + * Returns 0 if access is permitted, an error code otherwise 658 + */ 659 + static int smack_inode_removexattr(struct dentry *dentry, char *name) 660 + { 661 + if (strcmp(name, XATTR_NAME_SMACK) == 0 && !capable(CAP_MAC_ADMIN)) 662 + return -EPERM; 663 + 664 + return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); 665 + } 666 + 667 + /** 668 + * smack_inode_getsecurity - get smack xattrs 669 + * @inode: the object 670 + * @name: attribute name 671 + * @buffer: where to put the result 672 + * @size: size of the buffer 673 + * @err: unused 674 + * 675 + * Returns the size of the attribute or an error code 676 + */ 677 + static int smack_inode_getsecurity(const struct inode *inode, 678 + const char *name, void **buffer, 679 + bool alloc) 680 + { 681 + struct socket_smack *ssp; 682 + struct socket *sock; 683 + struct super_block *sbp; 684 + struct inode *ip = (struct inode *)inode; 685 + char *isp; 686 + int ilen; 687 + int rc = 0; 688 + 689 + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { 690 + isp = smk_of_inode(inode); 691 + ilen = strlen(isp) + 1; 692 + *buffer = isp; 693 + return ilen; 694 + } 695 + 696 + /* 697 + * The rest of the Smack xattrs are only on sockets. 698 + */ 699 + sbp = ip->i_sb; 700 + if (sbp->s_magic != SOCKFS_MAGIC) 701 + return -EOPNOTSUPP; 702 + 703 + sock = SOCKET_I(ip); 704 + if (sock == NULL) 705 + return -EOPNOTSUPP; 706 + 707 + ssp = sock->sk->sk_security; 708 + 709 + if (strcmp(name, XATTR_SMACK_IPIN) == 0) 710 + isp = ssp->smk_in; 711 + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) 712 + isp = ssp->smk_out; 713 + else 714 + return -EOPNOTSUPP; 715 + 716 + ilen = strlen(isp) + 1; 717 + if (rc == 0) { 718 + *buffer = isp; 719 + rc = ilen; 720 + } 721 + 722 + return rc; 723 + } 724 + 725 + 726 + /** 727 + * smack_inode_listsecurity - list the Smack attributes 728 + * @inode: the object 729 + * @buffer: where they go 730 + * @buffer_size: size of buffer 731 + * 732 + * Returns 0 on success, -EINVAL otherwise 733 + */ 734 + static int smack_inode_listsecurity(struct inode *inode, char *buffer, 735 + size_t buffer_size) 736 + { 737 + int len = strlen(XATTR_NAME_SMACK); 738 + 739 + if (buffer != NULL && len <= buffer_size) { 740 + memcpy(buffer, XATTR_NAME_SMACK, len); 741 + return len; 742 + } 743 + return -EINVAL; 744 + } 745 + 746 + /* 747 + * File Hooks 748 + */ 749 + 750 + /** 751 + * smack_file_permission - Smack check on file operations 752 + * @file: unused 753 + * @mask: unused 754 + * 755 + * Returns 0 756 + * 757 + * Should access checks be done on each read or write? 758 + * UNICOS and SELinux say yes. 759 + * Trusted Solaris, Trusted Irix, and just about everyone else says no. 760 + * 761 + * I'll say no for now. Smack does not do the frequent 762 + * label changing that SELinux does. 763 + */ 764 + static int smack_file_permission(struct file *file, int mask) 765 + { 766 + return 0; 767 + } 768 + 769 + /** 770 + * smack_file_alloc_security - assign a file security blob 771 + * @file: the object 772 + * 773 + * The security blob for a file is a pointer to the master 774 + * label list, so no allocation is done. 775 + * 776 + * Returns 0 777 + */ 778 + static int smack_file_alloc_security(struct file *file) 779 + { 780 + file->f_security = current->security; 781 + return 0; 782 + } 783 + 784 + /** 785 + * smack_file_free_security - clear a file security blob 786 + * @file: the object 787 + * 788 + * The security blob for a file is a pointer to the master 789 + * label list, so no memory is freed. 790 + */ 791 + static void smack_file_free_security(struct file *file) 792 + { 793 + file->f_security = NULL; 794 + } 795 + 796 + /** 797 + * smack_file_ioctl - Smack check on ioctls 798 + * @file: the object 799 + * @cmd: what to do 800 + * @arg: unused 801 + * 802 + * Relies heavily on the correct use of the ioctl command conventions. 803 + * 804 + * Returns 0 if allowed, error code otherwise 805 + */ 806 + static int smack_file_ioctl(struct file *file, unsigned int cmd, 807 + unsigned long arg) 808 + { 809 + int rc = 0; 810 + 811 + if (_IOC_DIR(cmd) & _IOC_WRITE) 812 + rc = smk_curacc(file->f_security, MAY_WRITE); 813 + 814 + if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) 815 + rc = smk_curacc(file->f_security, MAY_READ); 816 + 817 + return rc; 818 + } 819 + 820 + /** 821 + * smack_file_lock - Smack check on file locking 822 + * @file: the object 823 + * @cmd unused 824 + * 825 + * Returns 0 if current has write access, error code otherwise 826 + */ 827 + static int smack_file_lock(struct file *file, unsigned int cmd) 828 + { 829 + return smk_curacc(file->f_security, MAY_WRITE); 830 + } 831 + 832 + /** 833 + * smack_file_fcntl - Smack check on fcntl 834 + * @file: the object 835 + * @cmd: what action to check 836 + * @arg: unused 837 + * 838 + * Returns 0 if current has access, error code otherwise 839 + */ 840 + static int smack_file_fcntl(struct file *file, unsigned int cmd, 841 + unsigned long arg) 842 + { 843 + int rc; 844 + 845 + switch (cmd) { 846 + case F_DUPFD: 847 + case F_GETFD: 848 + case F_GETFL: 849 + case F_GETLK: 850 + case F_GETOWN: 851 + case F_GETSIG: 852 + rc = smk_curacc(file->f_security, MAY_READ); 853 + break; 854 + case F_SETFD: 855 + case F_SETFL: 856 + case F_SETLK: 857 + case F_SETLKW: 858 + case F_SETOWN: 859 + case F_SETSIG: 860 + rc = smk_curacc(file->f_security, MAY_WRITE); 861 + break; 862 + default: 863 + rc = smk_curacc(file->f_security, MAY_READWRITE); 864 + } 865 + 866 + return rc; 867 + } 868 + 869 + /** 870 + * smack_file_set_fowner - set the file security blob value 871 + * @file: object in question 872 + * 873 + * Returns 0 874 + * Further research may be required on this one. 875 + */ 876 + static int smack_file_set_fowner(struct file *file) 877 + { 878 + file->f_security = current->security; 879 + return 0; 880 + } 881 + 882 + /** 883 + * smack_file_send_sigiotask - Smack on sigio 884 + * @tsk: The target task 885 + * @fown: the object the signal come from 886 + * @signum: unused 887 + * 888 + * Allow a privileged task to get signals even if it shouldn't 889 + * 890 + * Returns 0 if a subject with the object's smack could 891 + * write to the task, an error code otherwise. 892 + */ 893 + static int smack_file_send_sigiotask(struct task_struct *tsk, 894 + struct fown_struct *fown, int signum) 895 + { 896 + struct file *file; 897 + int rc; 898 + 899 + /* 900 + * struct fown_struct is never outside the context of a struct file 901 + */ 902 + file = container_of(fown, struct file, f_owner); 903 + rc = smk_access(file->f_security, tsk->security, MAY_WRITE); 904 + if (rc != 0 && __capable(tsk, CAP_MAC_OVERRIDE)) 905 + return 0; 906 + return rc; 907 + } 908 + 909 + /** 910 + * smack_file_receive - Smack file receive check 911 + * @file: the object 912 + * 913 + * Returns 0 if current has access, error code otherwise 914 + */ 915 + static int smack_file_receive(struct file *file) 916 + { 917 + int may = 0; 918 + 919 + /* 920 + * This code relies on bitmasks. 921 + */ 922 + if (file->f_mode & FMODE_READ) 923 + may = MAY_READ; 924 + if (file->f_mode & FMODE_WRITE) 925 + may |= MAY_WRITE; 926 + 927 + return smk_curacc(file->f_security, may); 928 + } 929 + 930 + /* 931 + * Task hooks 932 + */ 933 + 934 + /** 935 + * smack_task_alloc_security - "allocate" a task blob 936 + * @tsk: the task in need of a blob 937 + * 938 + * Smack isn't using copies of blobs. Everyone 939 + * points to an immutable list. No alloc required. 940 + * No data copy required. 941 + * 942 + * Always returns 0 943 + */ 944 + static int smack_task_alloc_security(struct task_struct *tsk) 945 + { 946 + tsk->security = current->security; 947 + 948 + return 0; 949 + } 950 + 951 + /** 952 + * smack_task_free_security - "free" a task blob 953 + * @task: the task with the blob 954 + * 955 + * Smack isn't using copies of blobs. Everyone 956 + * points to an immutable list. The blobs never go away. 957 + * There is no leak here. 958 + */ 959 + static void smack_task_free_security(struct task_struct *task) 960 + { 961 + task->security = NULL; 962 + } 963 + 964 + /** 965 + * smack_task_setpgid - Smack check on setting pgid 966 + * @p: the task object 967 + * @pgid: unused 968 + * 969 + * Return 0 if write access is permitted 970 + */ 971 + static int smack_task_setpgid(struct task_struct *p, pid_t pgid) 972 + { 973 + return smk_curacc(p->security, MAY_WRITE); 974 + } 975 + 976 + /** 977 + * smack_task_getpgid - Smack access check for getpgid 978 + * @p: the object task 979 + * 980 + * Returns 0 if current can read the object task, error code otherwise 981 + */ 982 + static int smack_task_getpgid(struct task_struct *p) 983 + { 984 + return smk_curacc(p->security, MAY_READ); 985 + } 986 + 987 + /** 988 + * smack_task_getsid - Smack access check for getsid 989 + * @p: the object task 990 + * 991 + * Returns 0 if current can read the object task, error code otherwise 992 + */ 993 + static int smack_task_getsid(struct task_struct *p) 994 + { 995 + return smk_curacc(p->security, MAY_READ); 996 + } 997 + 998 + /** 999 + * smack_task_getsecid - get the secid of the task 1000 + * @p: the object task 1001 + * @secid: where to put the result 1002 + * 1003 + * Sets the secid to contain a u32 version of the smack label. 1004 + */ 1005 + static void smack_task_getsecid(struct task_struct *p, u32 *secid) 1006 + { 1007 + *secid = smack_to_secid(p->security); 1008 + } 1009 + 1010 + /** 1011 + * smack_task_setnice - Smack check on setting nice 1012 + * @p: the task object 1013 + * @nice: unused 1014 + * 1015 + * Return 0 if write access is permitted 1016 + */ 1017 + static int smack_task_setnice(struct task_struct *p, int nice) 1018 + { 1019 + return smk_curacc(p->security, MAY_WRITE); 1020 + } 1021 + 1022 + /** 1023 + * smack_task_setioprio - Smack check on setting ioprio 1024 + * @p: the task object 1025 + * @ioprio: unused 1026 + * 1027 + * Return 0 if write access is permitted 1028 + */ 1029 + static int smack_task_setioprio(struct task_struct *p, int ioprio) 1030 + { 1031 + return smk_curacc(p->security, MAY_WRITE); 1032 + } 1033 + 1034 + /** 1035 + * smack_task_getioprio - Smack check on reading ioprio 1036 + * @p: the task object 1037 + * 1038 + * Return 0 if read access is permitted 1039 + */ 1040 + static int smack_task_getioprio(struct task_struct *p) 1041 + { 1042 + return smk_curacc(p->security, MAY_READ); 1043 + } 1044 + 1045 + /** 1046 + * smack_task_setscheduler - Smack check on setting scheduler 1047 + * @p: the task object 1048 + * @policy: unused 1049 + * @lp: unused 1050 + * 1051 + * Return 0 if read access is permitted 1052 + */ 1053 + static int smack_task_setscheduler(struct task_struct *p, int policy, 1054 + struct sched_param *lp) 1055 + { 1056 + return smk_curacc(p->security, MAY_WRITE); 1057 + } 1058 + 1059 + /** 1060 + * smack_task_getscheduler - Smack check on reading scheduler 1061 + * @p: the task object 1062 + * 1063 + * Return 0 if read access is permitted 1064 + */ 1065 + static int smack_task_getscheduler(struct task_struct *p) 1066 + { 1067 + return smk_curacc(p->security, MAY_READ); 1068 + } 1069 + 1070 + /** 1071 + * smack_task_movememory - Smack check on moving memory 1072 + * @p: the task object 1073 + * 1074 + * Return 0 if write access is permitted 1075 + */ 1076 + static int smack_task_movememory(struct task_struct *p) 1077 + { 1078 + return smk_curacc(p->security, MAY_WRITE); 1079 + } 1080 + 1081 + /** 1082 + * smack_task_kill - Smack check on signal delivery 1083 + * @p: the task object 1084 + * @info: unused 1085 + * @sig: unused 1086 + * @secid: identifies the smack to use in lieu of current's 1087 + * 1088 + * Return 0 if write access is permitted 1089 + * 1090 + * The secid behavior is an artifact of an SELinux hack 1091 + * in the USB code. Someday it may go away. 1092 + */ 1093 + static int smack_task_kill(struct task_struct *p, struct siginfo *info, 1094 + int sig, u32 secid) 1095 + { 1096 + /* 1097 + * Special cases where signals really ought to go through 1098 + * in spite of policy. Stephen Smalley suggests it may 1099 + * make sense to change the caller so that it doesn't 1100 + * bother with the LSM hook in these cases. 1101 + */ 1102 + if (info != SEND_SIG_NOINFO && 1103 + (is_si_special(info) || SI_FROMKERNEL(info))) 1104 + return 0; 1105 + /* 1106 + * Sending a signal requires that the sender 1107 + * can write the receiver. 1108 + */ 1109 + if (secid == 0) 1110 + return smk_curacc(p->security, MAY_WRITE); 1111 + /* 1112 + * If the secid isn't 0 we're dealing with some USB IO 1113 + * specific behavior. This is not clean. For one thing 1114 + * we can't take privilege into account. 1115 + */ 1116 + return smk_access(smack_from_secid(secid), p->security, MAY_WRITE); 1117 + } 1118 + 1119 + /** 1120 + * smack_task_wait - Smack access check for waiting 1121 + * @p: task to wait for 1122 + * 1123 + * Returns 0 if current can wait for p, error code otherwise 1124 + */ 1125 + static int smack_task_wait(struct task_struct *p) 1126 + { 1127 + int rc; 1128 + 1129 + rc = smk_access(current->security, p->security, MAY_WRITE); 1130 + if (rc == 0) 1131 + return 0; 1132 + 1133 + /* 1134 + * Allow the operation to succeed if either task 1135 + * has privilege to perform operations that might 1136 + * account for the smack labels having gotten to 1137 + * be different in the first place. 1138 + * 1139 + * This breaks the strict subjet/object access 1140 + * control ideal, taking the object's privilege 1141 + * state into account in the decision as well as 1142 + * the smack value. 1143 + */ 1144 + if (capable(CAP_MAC_OVERRIDE) || __capable(p, CAP_MAC_OVERRIDE)) 1145 + return 0; 1146 + 1147 + return rc; 1148 + } 1149 + 1150 + /** 1151 + * smack_task_to_inode - copy task smack into the inode blob 1152 + * @p: task to copy from 1153 + * inode: inode to copy to 1154 + * 1155 + * Sets the smack pointer in the inode security blob 1156 + */ 1157 + static void smack_task_to_inode(struct task_struct *p, struct inode *inode) 1158 + { 1159 + struct inode_smack *isp = inode->i_security; 1160 + isp->smk_inode = p->security; 1161 + } 1162 + 1163 + /* 1164 + * Socket hooks. 1165 + */ 1166 + 1167 + /** 1168 + * smack_sk_alloc_security - Allocate a socket blob 1169 + * @sk: the socket 1170 + * @family: unused 1171 + * @priority: memory allocation priority 1172 + * 1173 + * Assign Smack pointers to current 1174 + * 1175 + * Returns 0 on success, -ENOMEM is there's no memory 1176 + */ 1177 + static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) 1178 + { 1179 + char *csp = current->security; 1180 + struct socket_smack *ssp; 1181 + 1182 + ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); 1183 + if (ssp == NULL) 1184 + return -ENOMEM; 1185 + 1186 + ssp->smk_in = csp; 1187 + ssp->smk_out = csp; 1188 + ssp->smk_packet[0] = '\0'; 1189 + 1190 + sk->sk_security = ssp; 1191 + 1192 + return 0; 1193 + } 1194 + 1195 + /** 1196 + * smack_sk_free_security - Free a socket blob 1197 + * @sk: the socket 1198 + * 1199 + * Clears the blob pointer 1200 + */ 1201 + static void smack_sk_free_security(struct sock *sk) 1202 + { 1203 + kfree(sk->sk_security); 1204 + } 1205 + 1206 + /** 1207 + * smack_set_catset - convert a capset to netlabel mls categories 1208 + * @catset: the Smack categories 1209 + * @sap: where to put the netlabel categories 1210 + * 1211 + * Allocates and fills attr.mls.cat 1212 + */ 1213 + static void smack_set_catset(char *catset, struct netlbl_lsm_secattr *sap) 1214 + { 1215 + unsigned char *cp; 1216 + unsigned char m; 1217 + int cat; 1218 + int rc; 1219 + int byte; 1220 + 1221 + if (catset == 0) 1222 + return; 1223 + 1224 + sap->flags |= NETLBL_SECATTR_MLS_CAT; 1225 + sap->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC); 1226 + sap->attr.mls.cat->startbit = 0; 1227 + 1228 + for (cat = 1, cp = catset, byte = 0; byte < SMK_LABELLEN; cp++, byte++) 1229 + for (m = 0x80; m != 0; m >>= 1, cat++) { 1230 + if ((m & *cp) == 0) 1231 + continue; 1232 + rc = netlbl_secattr_catmap_setbit(sap->attr.mls.cat, 1233 + cat, GFP_ATOMIC); 1234 + } 1235 + } 1236 + 1237 + /** 1238 + * smack_to_secattr - fill a secattr from a smack value 1239 + * @smack: the smack value 1240 + * @nlsp: where the result goes 1241 + * 1242 + * Casey says that CIPSO is good enough for now. 1243 + * It can be used to effect. 1244 + * It can also be abused to effect when necessary. 1245 + * Appologies to the TSIG group in general and GW in particular. 1246 + */ 1247 + static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) 1248 + { 1249 + struct smack_cipso cipso; 1250 + int rc; 1251 + 1252 + switch (smack_net_nltype) { 1253 + case NETLBL_NLTYPE_CIPSOV4: 1254 + nlsp->domain = NULL; 1255 + nlsp->flags = NETLBL_SECATTR_DOMAIN; 1256 + nlsp->flags |= NETLBL_SECATTR_MLS_LVL; 1257 + 1258 + rc = smack_to_cipso(smack, &cipso); 1259 + if (rc == 0) { 1260 + nlsp->attr.mls.lvl = cipso.smk_level; 1261 + smack_set_catset(cipso.smk_catset, nlsp); 1262 + } else { 1263 + nlsp->attr.mls.lvl = smack_cipso_direct; 1264 + smack_set_catset(smack, nlsp); 1265 + } 1266 + break; 1267 + default: 1268 + break; 1269 + } 1270 + } 1271 + 1272 + /** 1273 + * smack_netlabel - Set the secattr on a socket 1274 + * @sk: the socket 1275 + * 1276 + * Convert the outbound smack value (smk_out) to a 1277 + * secattr and attach it to the socket. 1278 + * 1279 + * Returns 0 on success or an error code 1280 + */ 1281 + static int smack_netlabel(struct sock *sk) 1282 + { 1283 + struct socket_smack *ssp = sk->sk_security; 1284 + struct netlbl_lsm_secattr secattr; 1285 + int rc = 0; 1286 + 1287 + netlbl_secattr_init(&secattr); 1288 + smack_to_secattr(ssp->smk_out, &secattr); 1289 + if (secattr.flags != NETLBL_SECATTR_NONE) 1290 + rc = netlbl_sock_setattr(sk, &secattr); 1291 + 1292 + netlbl_secattr_destroy(&secattr); 1293 + return rc; 1294 + } 1295 + 1296 + /** 1297 + * smack_inode_setsecurity - set smack xattrs 1298 + * @inode: the object 1299 + * @name: attribute name 1300 + * @value: attribute value 1301 + * @size: size of the attribute 1302 + * @flags: unused 1303 + * 1304 + * Sets the named attribute in the appropriate blob 1305 + * 1306 + * Returns 0 on success, or an error code 1307 + */ 1308 + static int smack_inode_setsecurity(struct inode *inode, const char *name, 1309 + const void *value, size_t size, int flags) 1310 + { 1311 + char *sp; 1312 + struct inode_smack *nsp = inode->i_security; 1313 + struct socket_smack *ssp; 1314 + struct socket *sock; 1315 + 1316 + if (value == NULL || size > SMK_LABELLEN) 1317 + return -EACCES; 1318 + 1319 + sp = smk_import(value, size); 1320 + if (sp == NULL) 1321 + return -EINVAL; 1322 + 1323 + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { 1324 + nsp->smk_inode = sp; 1325 + return 0; 1326 + } 1327 + /* 1328 + * The rest of the Smack xattrs are only on sockets. 1329 + */ 1330 + if (inode->i_sb->s_magic != SOCKFS_MAGIC) 1331 + return -EOPNOTSUPP; 1332 + 1333 + sock = SOCKET_I(inode); 1334 + if (sock == NULL) 1335 + return -EOPNOTSUPP; 1336 + 1337 + ssp = sock->sk->sk_security; 1338 + 1339 + if (strcmp(name, XATTR_SMACK_IPIN) == 0) 1340 + ssp->smk_in = sp; 1341 + else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 1342 + ssp->smk_out = sp; 1343 + return smack_netlabel(sock->sk); 1344 + } else 1345 + return -EOPNOTSUPP; 1346 + 1347 + return 0; 1348 + } 1349 + 1350 + /** 1351 + * smack_socket_post_create - finish socket setup 1352 + * @sock: the socket 1353 + * @family: protocol family 1354 + * @type: unused 1355 + * @protocol: unused 1356 + * @kern: unused 1357 + * 1358 + * Sets the netlabel information on the socket 1359 + * 1360 + * Returns 0 on success, and error code otherwise 1361 + */ 1362 + static int smack_socket_post_create(struct socket *sock, int family, 1363 + int type, int protocol, int kern) 1364 + { 1365 + if (family != PF_INET) 1366 + return 0; 1367 + /* 1368 + * Set the outbound netlbl. 1369 + */ 1370 + return smack_netlabel(sock->sk); 1371 + } 1372 + 1373 + /** 1374 + * smack_flags_to_may - convert S_ to MAY_ values 1375 + * @flags: the S_ value 1376 + * 1377 + * Returns the equivalent MAY_ value 1378 + */ 1379 + static int smack_flags_to_may(int flags) 1380 + { 1381 + int may = 0; 1382 + 1383 + if (flags & S_IRUGO) 1384 + may |= MAY_READ; 1385 + if (flags & S_IWUGO) 1386 + may |= MAY_WRITE; 1387 + if (flags & S_IXUGO) 1388 + may |= MAY_EXEC; 1389 + 1390 + return may; 1391 + } 1392 + 1393 + /** 1394 + * smack_msg_msg_alloc_security - Set the security blob for msg_msg 1395 + * @msg: the object 1396 + * 1397 + * Returns 0 1398 + */ 1399 + static int smack_msg_msg_alloc_security(struct msg_msg *msg) 1400 + { 1401 + msg->security = current->security; 1402 + return 0; 1403 + } 1404 + 1405 + /** 1406 + * smack_msg_msg_free_security - Clear the security blob for msg_msg 1407 + * @msg: the object 1408 + * 1409 + * Clears the blob pointer 1410 + */ 1411 + static void smack_msg_msg_free_security(struct msg_msg *msg) 1412 + { 1413 + msg->security = NULL; 1414 + } 1415 + 1416 + /** 1417 + * smack_of_shm - the smack pointer for the shm 1418 + * @shp: the object 1419 + * 1420 + * Returns a pointer to the smack value 1421 + */ 1422 + static char *smack_of_shm(struct shmid_kernel *shp) 1423 + { 1424 + return (char *)shp->shm_perm.security; 1425 + } 1426 + 1427 + /** 1428 + * smack_shm_alloc_security - Set the security blob for shm 1429 + * @shp: the object 1430 + * 1431 + * Returns 0 1432 + */ 1433 + static int smack_shm_alloc_security(struct shmid_kernel *shp) 1434 + { 1435 + struct kern_ipc_perm *isp = &shp->shm_perm; 1436 + 1437 + isp->security = current->security; 1438 + return 0; 1439 + } 1440 + 1441 + /** 1442 + * smack_shm_free_security - Clear the security blob for shm 1443 + * @shp: the object 1444 + * 1445 + * Clears the blob pointer 1446 + */ 1447 + static void smack_shm_free_security(struct shmid_kernel *shp) 1448 + { 1449 + struct kern_ipc_perm *isp = &shp->shm_perm; 1450 + 1451 + isp->security = NULL; 1452 + } 1453 + 1454 + /** 1455 + * smack_shm_associate - Smack access check for shm 1456 + * @shp: the object 1457 + * @shmflg: access requested 1458 + * 1459 + * Returns 0 if current has the requested access, error code otherwise 1460 + */ 1461 + static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) 1462 + { 1463 + char *ssp = smack_of_shm(shp); 1464 + int may; 1465 + 1466 + may = smack_flags_to_may(shmflg); 1467 + return smk_curacc(ssp, may); 1468 + } 1469 + 1470 + /** 1471 + * smack_shm_shmctl - Smack access check for shm 1472 + * @shp: the object 1473 + * @cmd: what it wants to do 1474 + * 1475 + * Returns 0 if current has the requested access, error code otherwise 1476 + */ 1477 + static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) 1478 + { 1479 + char *ssp = smack_of_shm(shp); 1480 + int may; 1481 + 1482 + switch (cmd) { 1483 + case IPC_STAT: 1484 + case SHM_STAT: 1485 + may = MAY_READ; 1486 + break; 1487 + case IPC_SET: 1488 + case SHM_LOCK: 1489 + case SHM_UNLOCK: 1490 + case IPC_RMID: 1491 + may = MAY_READWRITE; 1492 + break; 1493 + case IPC_INFO: 1494 + case SHM_INFO: 1495 + /* 1496 + * System level information. 1497 + */ 1498 + return 0; 1499 + default: 1500 + return -EINVAL; 1501 + } 1502 + 1503 + return smk_curacc(ssp, may); 1504 + } 1505 + 1506 + /** 1507 + * smack_shm_shmat - Smack access for shmat 1508 + * @shp: the object 1509 + * @shmaddr: unused 1510 + * @shmflg: access requested 1511 + * 1512 + * Returns 0 if current has the requested access, error code otherwise 1513 + */ 1514 + static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, 1515 + int shmflg) 1516 + { 1517 + char *ssp = smack_of_shm(shp); 1518 + int may; 1519 + 1520 + may = smack_flags_to_may(shmflg); 1521 + return smk_curacc(ssp, may); 1522 + } 1523 + 1524 + /** 1525 + * smack_of_sem - the smack pointer for the sem 1526 + * @sma: the object 1527 + * 1528 + * Returns a pointer to the smack value 1529 + */ 1530 + static char *smack_of_sem(struct sem_array *sma) 1531 + { 1532 + return (char *)sma->sem_perm.security; 1533 + } 1534 + 1535 + /** 1536 + * smack_sem_alloc_security - Set the security blob for sem 1537 + * @sma: the object 1538 + * 1539 + * Returns 0 1540 + */ 1541 + static int smack_sem_alloc_security(struct sem_array *sma) 1542 + { 1543 + struct kern_ipc_perm *isp = &sma->sem_perm; 1544 + 1545 + isp->security = current->security; 1546 + return 0; 1547 + } 1548 + 1549 + /** 1550 + * smack_sem_free_security - Clear the security blob for sem 1551 + * @sma: the object 1552 + * 1553 + * Clears the blob pointer 1554 + */ 1555 + static void smack_sem_free_security(struct sem_array *sma) 1556 + { 1557 + struct kern_ipc_perm *isp = &sma->sem_perm; 1558 + 1559 + isp->security = NULL; 1560 + } 1561 + 1562 + /** 1563 + * smack_sem_associate - Smack access check for sem 1564 + * @sma: the object 1565 + * @semflg: access requested 1566 + * 1567 + * Returns 0 if current has the requested access, error code otherwise 1568 + */ 1569 + static int smack_sem_associate(struct sem_array *sma, int semflg) 1570 + { 1571 + char *ssp = smack_of_sem(sma); 1572 + int may; 1573 + 1574 + may = smack_flags_to_may(semflg); 1575 + return smk_curacc(ssp, may); 1576 + } 1577 + 1578 + /** 1579 + * smack_sem_shmctl - Smack access check for sem 1580 + * @sma: the object 1581 + * @cmd: what it wants to do 1582 + * 1583 + * Returns 0 if current has the requested access, error code otherwise 1584 + */ 1585 + static int smack_sem_semctl(struct sem_array *sma, int cmd) 1586 + { 1587 + char *ssp = smack_of_sem(sma); 1588 + int may; 1589 + 1590 + switch (cmd) { 1591 + case GETPID: 1592 + case GETNCNT: 1593 + case GETZCNT: 1594 + case GETVAL: 1595 + case GETALL: 1596 + case IPC_STAT: 1597 + case SEM_STAT: 1598 + may = MAY_READ; 1599 + break; 1600 + case SETVAL: 1601 + case SETALL: 1602 + case IPC_RMID: 1603 + case IPC_SET: 1604 + may = MAY_READWRITE; 1605 + break; 1606 + case IPC_INFO: 1607 + case SEM_INFO: 1608 + /* 1609 + * System level information 1610 + */ 1611 + return 0; 1612 + default: 1613 + return -EINVAL; 1614 + } 1615 + 1616 + return smk_curacc(ssp, may); 1617 + } 1618 + 1619 + /** 1620 + * smack_sem_semop - Smack checks of semaphore operations 1621 + * @sma: the object 1622 + * @sops: unused 1623 + * @nsops: unused 1624 + * @alter: unused 1625 + * 1626 + * Treated as read and write in all cases. 1627 + * 1628 + * Returns 0 if access is allowed, error code otherwise 1629 + */ 1630 + static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, 1631 + unsigned nsops, int alter) 1632 + { 1633 + char *ssp = smack_of_sem(sma); 1634 + 1635 + return smk_curacc(ssp, MAY_READWRITE); 1636 + } 1637 + 1638 + /** 1639 + * smack_msg_alloc_security - Set the security blob for msg 1640 + * @msq: the object 1641 + * 1642 + * Returns 0 1643 + */ 1644 + static int smack_msg_queue_alloc_security(struct msg_queue *msq) 1645 + { 1646 + struct kern_ipc_perm *kisp = &msq->q_perm; 1647 + 1648 + kisp->security = current->security; 1649 + return 0; 1650 + } 1651 + 1652 + /** 1653 + * smack_msg_free_security - Clear the security blob for msg 1654 + * @msq: the object 1655 + * 1656 + * Clears the blob pointer 1657 + */ 1658 + static void smack_msg_queue_free_security(struct msg_queue *msq) 1659 + { 1660 + struct kern_ipc_perm *kisp = &msq->q_perm; 1661 + 1662 + kisp->security = NULL; 1663 + } 1664 + 1665 + /** 1666 + * smack_of_msq - the smack pointer for the msq 1667 + * @msq: the object 1668 + * 1669 + * Returns a pointer to the smack value 1670 + */ 1671 + static char *smack_of_msq(struct msg_queue *msq) 1672 + { 1673 + return (char *)msq->q_perm.security; 1674 + } 1675 + 1676 + /** 1677 + * smack_msg_queue_associate - Smack access check for msg_queue 1678 + * @msq: the object 1679 + * @msqflg: access requested 1680 + * 1681 + * Returns 0 if current has the requested access, error code otherwise 1682 + */ 1683 + static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) 1684 + { 1685 + char *msp = smack_of_msq(msq); 1686 + int may; 1687 + 1688 + may = smack_flags_to_may(msqflg); 1689 + return smk_curacc(msp, may); 1690 + } 1691 + 1692 + /** 1693 + * smack_msg_queue_msgctl - Smack access check for msg_queue 1694 + * @msq: the object 1695 + * @cmd: what it wants to do 1696 + * 1697 + * Returns 0 if current has the requested access, error code otherwise 1698 + */ 1699 + static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) 1700 + { 1701 + char *msp = smack_of_msq(msq); 1702 + int may; 1703 + 1704 + switch (cmd) { 1705 + case IPC_STAT: 1706 + case MSG_STAT: 1707 + may = MAY_READ; 1708 + break; 1709 + case IPC_SET: 1710 + case IPC_RMID: 1711 + may = MAY_READWRITE; 1712 + break; 1713 + case IPC_INFO: 1714 + case MSG_INFO: 1715 + /* 1716 + * System level information 1717 + */ 1718 + return 0; 1719 + default: 1720 + return -EINVAL; 1721 + } 1722 + 1723 + return smk_curacc(msp, may); 1724 + } 1725 + 1726 + /** 1727 + * smack_msg_queue_msgsnd - Smack access check for msg_queue 1728 + * @msq: the object 1729 + * @msg: unused 1730 + * @msqflg: access requested 1731 + * 1732 + * Returns 0 if current has the requested access, error code otherwise 1733 + */ 1734 + static int smack_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, 1735 + int msqflg) 1736 + { 1737 + char *msp = smack_of_msq(msq); 1738 + int rc; 1739 + 1740 + rc = smack_flags_to_may(msqflg); 1741 + return smk_curacc(msp, rc); 1742 + } 1743 + 1744 + /** 1745 + * smack_msg_queue_msgsnd - Smack access check for msg_queue 1746 + * @msq: the object 1747 + * @msg: unused 1748 + * @target: unused 1749 + * @type: unused 1750 + * @mode: unused 1751 + * 1752 + * Returns 0 if current has read and write access, error code otherwise 1753 + */ 1754 + static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, 1755 + struct task_struct *target, long type, int mode) 1756 + { 1757 + char *msp = smack_of_msq(msq); 1758 + 1759 + return smk_curacc(msp, MAY_READWRITE); 1760 + } 1761 + 1762 + /** 1763 + * smack_ipc_permission - Smack access for ipc_permission() 1764 + * @ipp: the object permissions 1765 + * @flag: access requested 1766 + * 1767 + * Returns 0 if current has read and write access, error code otherwise 1768 + */ 1769 + static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) 1770 + { 1771 + char *isp = ipp->security; 1772 + int may; 1773 + 1774 + may = smack_flags_to_may(flag); 1775 + return smk_curacc(isp, may); 1776 + } 1777 + 1778 + /** 1779 + * smack_d_instantiate - Make sure the blob is correct on an inode 1780 + * @opt_dentry: unused 1781 + * @inode: the object 1782 + * 1783 + * Set the inode's security blob if it hasn't been done already. 1784 + */ 1785 + static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) 1786 + { 1787 + struct super_block *sbp; 1788 + struct superblock_smack *sbsp; 1789 + struct inode_smack *isp; 1790 + char *csp = current->security; 1791 + char *fetched; 1792 + char *final; 1793 + struct dentry *dp; 1794 + 1795 + if (inode == NULL) 1796 + return; 1797 + 1798 + isp = inode->i_security; 1799 + 1800 + mutex_lock(&isp->smk_lock); 1801 + /* 1802 + * If the inode is already instantiated 1803 + * take the quick way out 1804 + */ 1805 + if (isp->smk_flags & SMK_INODE_INSTANT) 1806 + goto unlockandout; 1807 + 1808 + sbp = inode->i_sb; 1809 + sbsp = sbp->s_security; 1810 + /* 1811 + * We're going to use the superblock default label 1812 + * if there's no label on the file. 1813 + */ 1814 + final = sbsp->smk_default; 1815 + 1816 + /* 1817 + * This is pretty hackish. 1818 + * Casey says that we shouldn't have to do 1819 + * file system specific code, but it does help 1820 + * with keeping it simple. 1821 + */ 1822 + switch (sbp->s_magic) { 1823 + case SMACK_MAGIC: 1824 + /* 1825 + * Casey says that it's a little embarassing 1826 + * that the smack file system doesn't do 1827 + * extended attributes. 1828 + */ 1829 + final = smack_known_star.smk_known; 1830 + break; 1831 + case PIPEFS_MAGIC: 1832 + /* 1833 + * Casey says pipes are easy (?) 1834 + */ 1835 + final = smack_known_star.smk_known; 1836 + break; 1837 + case DEVPTS_SUPER_MAGIC: 1838 + /* 1839 + * devpts seems content with the label of the task. 1840 + * Programs that change smack have to treat the 1841 + * pty with respect. 1842 + */ 1843 + final = csp; 1844 + break; 1845 + case SOCKFS_MAGIC: 1846 + /* 1847 + * Casey says sockets get the smack of the task. 1848 + */ 1849 + final = csp; 1850 + break; 1851 + case PROC_SUPER_MAGIC: 1852 + /* 1853 + * Casey says procfs appears not to care. 1854 + * The superblock default suffices. 1855 + */ 1856 + break; 1857 + case TMPFS_MAGIC: 1858 + /* 1859 + * Device labels should come from the filesystem, 1860 + * but watch out, because they're volitile, 1861 + * getting recreated on every reboot. 1862 + */ 1863 + final = smack_known_star.smk_known; 1864 + /* 1865 + * No break. 1866 + * 1867 + * If a smack value has been set we want to use it, 1868 + * but since tmpfs isn't giving us the opportunity 1869 + * to set mount options simulate setting the 1870 + * superblock default. 1871 + */ 1872 + default: 1873 + /* 1874 + * This isn't an understood special case. 1875 + * Get the value from the xattr. 1876 + * 1877 + * No xattr support means, alas, no SMACK label. 1878 + * Use the aforeapplied default. 1879 + * It would be curious if the label of the task 1880 + * does not match that assigned. 1881 + */ 1882 + if (inode->i_op->getxattr == NULL) 1883 + break; 1884 + /* 1885 + * Get the dentry for xattr. 1886 + */ 1887 + if (opt_dentry == NULL) { 1888 + dp = d_find_alias(inode); 1889 + if (dp == NULL) 1890 + break; 1891 + } else { 1892 + dp = dget(opt_dentry); 1893 + if (dp == NULL) 1894 + break; 1895 + } 1896 + 1897 + fetched = smk_fetch(inode, dp); 1898 + if (fetched != NULL) 1899 + final = fetched; 1900 + 1901 + dput(dp); 1902 + break; 1903 + } 1904 + 1905 + if (final == NULL) 1906 + isp->smk_inode = csp; 1907 + else 1908 + isp->smk_inode = final; 1909 + 1910 + isp->smk_flags |= SMK_INODE_INSTANT; 1911 + 1912 + unlockandout: 1913 + mutex_unlock(&isp->smk_lock); 1914 + return; 1915 + } 1916 + 1917 + /** 1918 + * smack_getprocattr - Smack process attribute access 1919 + * @p: the object task 1920 + * @name: the name of the attribute in /proc/.../attr 1921 + * @value: where to put the result 1922 + * 1923 + * Places a copy of the task Smack into value 1924 + * 1925 + * Returns the length of the smack label or an error code 1926 + */ 1927 + static int smack_getprocattr(struct task_struct *p, char *name, char **value) 1928 + { 1929 + char *cp; 1930 + int slen; 1931 + 1932 + if (strcmp(name, "current") != 0) 1933 + return -EINVAL; 1934 + 1935 + cp = kstrdup(p->security, GFP_KERNEL); 1936 + if (cp == NULL) 1937 + return -ENOMEM; 1938 + 1939 + slen = strlen(cp); 1940 + *value = cp; 1941 + return slen; 1942 + } 1943 + 1944 + /** 1945 + * smack_setprocattr - Smack process attribute setting 1946 + * @p: the object task 1947 + * @name: the name of the attribute in /proc/.../attr 1948 + * @value: the value to set 1949 + * @size: the size of the value 1950 + * 1951 + * Sets the Smack value of the task. Only setting self 1952 + * is permitted and only with privilege 1953 + * 1954 + * Returns the length of the smack label or an error code 1955 + */ 1956 + static int smack_setprocattr(struct task_struct *p, char *name, 1957 + void *value, size_t size) 1958 + { 1959 + char *newsmack; 1960 + 1961 + if (!__capable(p, CAP_MAC_ADMIN)) 1962 + return -EPERM; 1963 + 1964 + /* 1965 + * Changing another process' Smack value is too dangerous 1966 + * and supports no sane use case. 1967 + */ 1968 + if (p != current) 1969 + return -EPERM; 1970 + 1971 + if (value == NULL || size == 0 || size >= SMK_LABELLEN) 1972 + return -EINVAL; 1973 + 1974 + if (strcmp(name, "current") != 0) 1975 + return -EINVAL; 1976 + 1977 + newsmack = smk_import(value, size); 1978 + if (newsmack == NULL) 1979 + return -EINVAL; 1980 + 1981 + p->security = newsmack; 1982 + return size; 1983 + } 1984 + 1985 + /** 1986 + * smack_unix_stream_connect - Smack access on UDS 1987 + * @sock: one socket 1988 + * @other: the other socket 1989 + * @newsk: unused 1990 + * 1991 + * Return 0 if a subject with the smack of sock could access 1992 + * an object with the smack of other, otherwise an error code 1993 + */ 1994 + static int smack_unix_stream_connect(struct socket *sock, 1995 + struct socket *other, struct sock *newsk) 1996 + { 1997 + struct inode *sp = SOCK_INODE(sock); 1998 + struct inode *op = SOCK_INODE(other); 1999 + 2000 + return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_READWRITE); 2001 + } 2002 + 2003 + /** 2004 + * smack_unix_may_send - Smack access on UDS 2005 + * @sock: one socket 2006 + * @other: the other socket 2007 + * 2008 + * Return 0 if a subject with the smack of sock could access 2009 + * an object with the smack of other, otherwise an error code 2010 + */ 2011 + static int smack_unix_may_send(struct socket *sock, struct socket *other) 2012 + { 2013 + struct inode *sp = SOCK_INODE(sock); 2014 + struct inode *op = SOCK_INODE(other); 2015 + 2016 + return smk_access(smk_of_inode(sp), smk_of_inode(op), MAY_WRITE); 2017 + } 2018 + 2019 + /** 2020 + * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat 2021 + * pair to smack 2022 + * @sap: netlabel secattr 2023 + * @sip: where to put the result 2024 + * 2025 + * Copies a smack label into sip 2026 + */ 2027 + static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip) 2028 + { 2029 + char smack[SMK_LABELLEN]; 2030 + int pcat; 2031 + 2032 + if ((sap->flags & NETLBL_SECATTR_MLS_LVL) == 0) { 2033 + /* 2034 + * If there are flags but no level netlabel isn't 2035 + * behaving the way we expect it to. 2036 + * 2037 + * Without guidance regarding the smack value 2038 + * for the packet fall back on the network 2039 + * ambient value. 2040 + */ 2041 + strncpy(sip, smack_net_ambient, SMK_MAXLEN); 2042 + return; 2043 + } 2044 + /* 2045 + * Get the categories, if any 2046 + */ 2047 + memset(smack, '\0', SMK_LABELLEN); 2048 + if ((sap->flags & NETLBL_SECATTR_MLS_CAT) != 0) 2049 + for (pcat = -1;;) { 2050 + pcat = netlbl_secattr_catmap_walk(sap->attr.mls.cat, 2051 + pcat + 1); 2052 + if (pcat < 0) 2053 + break; 2054 + smack_catset_bit(pcat, smack); 2055 + } 2056 + /* 2057 + * If it is CIPSO using smack direct mapping 2058 + * we are already done. WeeHee. 2059 + */ 2060 + if (sap->attr.mls.lvl == smack_cipso_direct) { 2061 + memcpy(sip, smack, SMK_MAXLEN); 2062 + return; 2063 + } 2064 + /* 2065 + * Look it up in the supplied table if it is not a direct mapping. 2066 + */ 2067 + smack_from_cipso(sap->attr.mls.lvl, smack, sip); 2068 + return; 2069 + } 2070 + 2071 + /** 2072 + * smack_socket_sock_rcv_skb - Smack packet delivery access check 2073 + * @sk: socket 2074 + * @skb: packet 2075 + * 2076 + * Returns 0 if the packet should be delivered, an error code otherwise 2077 + */ 2078 + static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) 2079 + { 2080 + struct netlbl_lsm_secattr secattr; 2081 + struct socket_smack *ssp = sk->sk_security; 2082 + char smack[SMK_LABELLEN]; 2083 + int rc; 2084 + 2085 + if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 2086 + return 0; 2087 + 2088 + /* 2089 + * Translate what netlabel gave us. 2090 + */ 2091 + memset(smack, '\0', SMK_LABELLEN); 2092 + netlbl_secattr_init(&secattr); 2093 + rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 2094 + if (rc == 0) 2095 + smack_from_secattr(&secattr, smack); 2096 + else 2097 + strncpy(smack, smack_net_ambient, SMK_MAXLEN); 2098 + netlbl_secattr_destroy(&secattr); 2099 + /* 2100 + * Receiving a packet requires that the other end 2101 + * be able to write here. Read access is not required. 2102 + * This is the simplist possible security model 2103 + * for networking. 2104 + */ 2105 + return smk_access(smack, ssp->smk_in, MAY_WRITE); 2106 + } 2107 + 2108 + /** 2109 + * smack_socket_getpeersec_stream - pull in packet label 2110 + * @sock: the socket 2111 + * @optval: user's destination 2112 + * @optlen: size thereof 2113 + * @len: max thereoe 2114 + * 2115 + * returns zero on success, an error code otherwise 2116 + */ 2117 + static int smack_socket_getpeersec_stream(struct socket *sock, 2118 + char __user *optval, 2119 + int __user *optlen, unsigned len) 2120 + { 2121 + struct socket_smack *ssp; 2122 + int slen; 2123 + int rc = 0; 2124 + 2125 + ssp = sock->sk->sk_security; 2126 + slen = strlen(ssp->smk_packet) + 1; 2127 + 2128 + if (slen > len) 2129 + rc = -ERANGE; 2130 + else if (copy_to_user(optval, ssp->smk_packet, slen) != 0) 2131 + rc = -EFAULT; 2132 + 2133 + if (put_user(slen, optlen) != 0) 2134 + rc = -EFAULT; 2135 + 2136 + return rc; 2137 + } 2138 + 2139 + 2140 + /** 2141 + * smack_socket_getpeersec_dgram - pull in packet label 2142 + * @sock: the socket 2143 + * @skb: packet data 2144 + * @secid: pointer to where to put the secid of the packet 2145 + * 2146 + * Sets the netlabel socket state on sk from parent 2147 + */ 2148 + static int smack_socket_getpeersec_dgram(struct socket *sock, 2149 + struct sk_buff *skb, u32 *secid) 2150 + 2151 + { 2152 + struct netlbl_lsm_secattr secattr; 2153 + struct sock *sk; 2154 + char smack[SMK_LABELLEN]; 2155 + int family = PF_INET; 2156 + u32 s; 2157 + int rc; 2158 + 2159 + /* 2160 + * Only works for families with packets. 2161 + */ 2162 + if (sock != NULL) { 2163 + sk = sock->sk; 2164 + if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 2165 + return 0; 2166 + family = sk->sk_family; 2167 + } 2168 + /* 2169 + * Translate what netlabel gave us. 2170 + */ 2171 + memset(smack, '\0', SMK_LABELLEN); 2172 + netlbl_secattr_init(&secattr); 2173 + rc = netlbl_skbuff_getattr(skb, family, &secattr); 2174 + if (rc == 0) 2175 + smack_from_secattr(&secattr, smack); 2176 + netlbl_secattr_destroy(&secattr); 2177 + 2178 + /* 2179 + * Give up if we couldn't get anything 2180 + */ 2181 + if (rc != 0) 2182 + return rc; 2183 + 2184 + s = smack_to_secid(smack); 2185 + if (s == 0) 2186 + return -EINVAL; 2187 + 2188 + *secid = s; 2189 + return 0; 2190 + } 2191 + 2192 + /** 2193 + * smack_sock_graft - graft access state between two sockets 2194 + * @sk: fresh sock 2195 + * @parent: donor socket 2196 + * 2197 + * Sets the netlabel socket state on sk from parent 2198 + */ 2199 + static void smack_sock_graft(struct sock *sk, struct socket *parent) 2200 + { 2201 + struct socket_smack *ssp; 2202 + int rc; 2203 + 2204 + if (sk == NULL) 2205 + return; 2206 + 2207 + if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) 2208 + return; 2209 + 2210 + ssp = sk->sk_security; 2211 + ssp->smk_in = current->security; 2212 + ssp->smk_out = current->security; 2213 + ssp->smk_packet[0] = '\0'; 2214 + 2215 + rc = smack_netlabel(sk); 2216 + } 2217 + 2218 + /** 2219 + * smack_inet_conn_request - Smack access check on connect 2220 + * @sk: socket involved 2221 + * @skb: packet 2222 + * @req: unused 2223 + * 2224 + * Returns 0 if a task with the packet label could write to 2225 + * the socket, otherwise an error code 2226 + */ 2227 + static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, 2228 + struct request_sock *req) 2229 + { 2230 + struct netlbl_lsm_secattr skb_secattr; 2231 + struct socket_smack *ssp = sk->sk_security; 2232 + char smack[SMK_LABELLEN]; 2233 + int rc; 2234 + 2235 + if (skb == NULL) 2236 + return -EACCES; 2237 + 2238 + memset(smack, '\0', SMK_LABELLEN); 2239 + netlbl_secattr_init(&skb_secattr); 2240 + rc = netlbl_skbuff_getattr(skb, sk->sk_family, &skb_secattr); 2241 + if (rc == 0) 2242 + smack_from_secattr(&skb_secattr, smack); 2243 + else 2244 + strncpy(smack, smack_known_huh.smk_known, SMK_MAXLEN); 2245 + netlbl_secattr_destroy(&skb_secattr); 2246 + /* 2247 + * Receiving a packet requires that the other end 2248 + * be able to write here. Read access is not required. 2249 + * 2250 + * If the request is successful save the peer's label 2251 + * so that SO_PEERCRED can report it. 2252 + */ 2253 + rc = smk_access(smack, ssp->smk_in, MAY_WRITE); 2254 + if (rc == 0) 2255 + strncpy(ssp->smk_packet, smack, SMK_MAXLEN); 2256 + 2257 + return rc; 2258 + } 2259 + 2260 + /* 2261 + * Key management security hooks 2262 + * 2263 + * Casey has not tested key support very heavily. 2264 + * The permission check is most likely too restrictive. 2265 + * If you care about keys please have a look. 2266 + */ 2267 + #ifdef CONFIG_KEYS 2268 + 2269 + /** 2270 + * smack_key_alloc - Set the key security blob 2271 + * @key: object 2272 + * @tsk: the task associated with the key 2273 + * @flags: unused 2274 + * 2275 + * No allocation required 2276 + * 2277 + * Returns 0 2278 + */ 2279 + static int smack_key_alloc(struct key *key, struct task_struct *tsk, 2280 + unsigned long flags) 2281 + { 2282 + key->security = tsk->security; 2283 + return 0; 2284 + } 2285 + 2286 + /** 2287 + * smack_key_free - Clear the key security blob 2288 + * @key: the object 2289 + * 2290 + * Clear the blob pointer 2291 + */ 2292 + static void smack_key_free(struct key *key) 2293 + { 2294 + key->security = NULL; 2295 + } 2296 + 2297 + /* 2298 + * smack_key_permission - Smack access on a key 2299 + * @key_ref: gets to the object 2300 + * @context: task involved 2301 + * @perm: unused 2302 + * 2303 + * Return 0 if the task has read and write to the object, 2304 + * an error code otherwise 2305 + */ 2306 + static int smack_key_permission(key_ref_t key_ref, 2307 + struct task_struct *context, key_perm_t perm) 2308 + { 2309 + struct key *keyp; 2310 + 2311 + keyp = key_ref_to_ptr(key_ref); 2312 + if (keyp == NULL) 2313 + return -EINVAL; 2314 + /* 2315 + * If the key hasn't been initialized give it access so that 2316 + * it may do so. 2317 + */ 2318 + if (keyp->security == NULL) 2319 + return 0; 2320 + /* 2321 + * This should not occur 2322 + */ 2323 + if (context->security == NULL) 2324 + return -EACCES; 2325 + 2326 + return smk_access(context->security, keyp->security, MAY_READWRITE); 2327 + } 2328 + #endif /* CONFIG_KEYS */ 2329 + 2330 + /* 2331 + * smack_secid_to_secctx - return the smack label for a secid 2332 + * @secid: incoming integer 2333 + * @secdata: destination 2334 + * @seclen: how long it is 2335 + * 2336 + * Exists for networking code. 2337 + */ 2338 + static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) 2339 + { 2340 + char *sp = smack_from_secid(secid); 2341 + 2342 + *secdata = sp; 2343 + *seclen = strlen(sp); 2344 + return 0; 2345 + } 2346 + 2347 + /* 2348 + * smack_release_secctx - don't do anything. 2349 + * @key_ref: unused 2350 + * @context: unused 2351 + * @perm: unused 2352 + * 2353 + * Exists to make sure nothing gets done, and properly 2354 + */ 2355 + static void smack_release_secctx(char *secdata, u32 seclen) 2356 + { 2357 + } 2358 + 2359 + static struct security_operations smack_ops = { 2360 + .ptrace = smack_ptrace, 2361 + .capget = cap_capget, 2362 + .capset_check = cap_capset_check, 2363 + .capset_set = cap_capset_set, 2364 + .capable = cap_capable, 2365 + .syslog = smack_syslog, 2366 + .settime = cap_settime, 2367 + .vm_enough_memory = cap_vm_enough_memory, 2368 + 2369 + .bprm_apply_creds = cap_bprm_apply_creds, 2370 + .bprm_set_security = cap_bprm_set_security, 2371 + .bprm_secureexec = cap_bprm_secureexec, 2372 + 2373 + .sb_alloc_security = smack_sb_alloc_security, 2374 + .sb_free_security = smack_sb_free_security, 2375 + .sb_copy_data = smack_sb_copy_data, 2376 + .sb_kern_mount = smack_sb_kern_mount, 2377 + .sb_statfs = smack_sb_statfs, 2378 + .sb_mount = smack_sb_mount, 2379 + .sb_umount = smack_sb_umount, 2380 + 2381 + .inode_alloc_security = smack_inode_alloc_security, 2382 + .inode_free_security = smack_inode_free_security, 2383 + .inode_init_security = smack_inode_init_security, 2384 + .inode_link = smack_inode_link, 2385 + .inode_unlink = smack_inode_unlink, 2386 + .inode_rmdir = smack_inode_rmdir, 2387 + .inode_rename = smack_inode_rename, 2388 + .inode_permission = smack_inode_permission, 2389 + .inode_setattr = smack_inode_setattr, 2390 + .inode_getattr = smack_inode_getattr, 2391 + .inode_setxattr = smack_inode_setxattr, 2392 + .inode_post_setxattr = smack_inode_post_setxattr, 2393 + .inode_getxattr = smack_inode_getxattr, 2394 + .inode_removexattr = smack_inode_removexattr, 2395 + .inode_getsecurity = smack_inode_getsecurity, 2396 + .inode_setsecurity = smack_inode_setsecurity, 2397 + .inode_listsecurity = smack_inode_listsecurity, 2398 + 2399 + .file_permission = smack_file_permission, 2400 + .file_alloc_security = smack_file_alloc_security, 2401 + .file_free_security = smack_file_free_security, 2402 + .file_ioctl = smack_file_ioctl, 2403 + .file_lock = smack_file_lock, 2404 + .file_fcntl = smack_file_fcntl, 2405 + .file_set_fowner = smack_file_set_fowner, 2406 + .file_send_sigiotask = smack_file_send_sigiotask, 2407 + .file_receive = smack_file_receive, 2408 + 2409 + .task_alloc_security = smack_task_alloc_security, 2410 + .task_free_security = smack_task_free_security, 2411 + .task_post_setuid = cap_task_post_setuid, 2412 + .task_setpgid = smack_task_setpgid, 2413 + .task_getpgid = smack_task_getpgid, 2414 + .task_getsid = smack_task_getsid, 2415 + .task_getsecid = smack_task_getsecid, 2416 + .task_setnice = smack_task_setnice, 2417 + .task_setioprio = smack_task_setioprio, 2418 + .task_getioprio = smack_task_getioprio, 2419 + .task_setscheduler = smack_task_setscheduler, 2420 + .task_getscheduler = smack_task_getscheduler, 2421 + .task_movememory = smack_task_movememory, 2422 + .task_kill = smack_task_kill, 2423 + .task_wait = smack_task_wait, 2424 + .task_reparent_to_init = cap_task_reparent_to_init, 2425 + .task_to_inode = smack_task_to_inode, 2426 + 2427 + .ipc_permission = smack_ipc_permission, 2428 + 2429 + .msg_msg_alloc_security = smack_msg_msg_alloc_security, 2430 + .msg_msg_free_security = smack_msg_msg_free_security, 2431 + 2432 + .msg_queue_alloc_security = smack_msg_queue_alloc_security, 2433 + .msg_queue_free_security = smack_msg_queue_free_security, 2434 + .msg_queue_associate = smack_msg_queue_associate, 2435 + .msg_queue_msgctl = smack_msg_queue_msgctl, 2436 + .msg_queue_msgsnd = smack_msg_queue_msgsnd, 2437 + .msg_queue_msgrcv = smack_msg_queue_msgrcv, 2438 + 2439 + .shm_alloc_security = smack_shm_alloc_security, 2440 + .shm_free_security = smack_shm_free_security, 2441 + .shm_associate = smack_shm_associate, 2442 + .shm_shmctl = smack_shm_shmctl, 2443 + .shm_shmat = smack_shm_shmat, 2444 + 2445 + .sem_alloc_security = smack_sem_alloc_security, 2446 + .sem_free_security = smack_sem_free_security, 2447 + .sem_associate = smack_sem_associate, 2448 + .sem_semctl = smack_sem_semctl, 2449 + .sem_semop = smack_sem_semop, 2450 + 2451 + .netlink_send = cap_netlink_send, 2452 + .netlink_recv = cap_netlink_recv, 2453 + 2454 + .d_instantiate = smack_d_instantiate, 2455 + 2456 + .getprocattr = smack_getprocattr, 2457 + .setprocattr = smack_setprocattr, 2458 + 2459 + .unix_stream_connect = smack_unix_stream_connect, 2460 + .unix_may_send = smack_unix_may_send, 2461 + 2462 + .socket_post_create = smack_socket_post_create, 2463 + .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, 2464 + .socket_getpeersec_stream = smack_socket_getpeersec_stream, 2465 + .socket_getpeersec_dgram = smack_socket_getpeersec_dgram, 2466 + .sk_alloc_security = smack_sk_alloc_security, 2467 + .sk_free_security = smack_sk_free_security, 2468 + .sock_graft = smack_sock_graft, 2469 + .inet_conn_request = smack_inet_conn_request, 2470 + /* key management security hooks */ 2471 + #ifdef CONFIG_KEYS 2472 + .key_alloc = smack_key_alloc, 2473 + .key_free = smack_key_free, 2474 + .key_permission = smack_key_permission, 2475 + #endif /* CONFIG_KEYS */ 2476 + .secid_to_secctx = smack_secid_to_secctx, 2477 + .release_secctx = smack_release_secctx, 2478 + }; 2479 + 2480 + /** 2481 + * smack_init - initialize the smack system 2482 + * 2483 + * Returns 0 2484 + */ 2485 + static __init int smack_init(void) 2486 + { 2487 + printk(KERN_INFO "Smack: Initializing.\n"); 2488 + 2489 + /* 2490 + * Set the security state for the initial task. 2491 + */ 2492 + current->security = &smack_known_floor.smk_known; 2493 + 2494 + /* 2495 + * Initialize locks 2496 + */ 2497 + spin_lock_init(&smack_known_unset.smk_cipsolock); 2498 + spin_lock_init(&smack_known_huh.smk_cipsolock); 2499 + spin_lock_init(&smack_known_hat.smk_cipsolock); 2500 + spin_lock_init(&smack_known_star.smk_cipsolock); 2501 + spin_lock_init(&smack_known_floor.smk_cipsolock); 2502 + spin_lock_init(&smack_known_invalid.smk_cipsolock); 2503 + 2504 + /* 2505 + * Register with LSM 2506 + */ 2507 + if (register_security(&smack_ops)) 2508 + panic("smack: Unable to register with kernel.\n"); 2509 + 2510 + return 0; 2511 + } 2512 + 2513 + /* 2514 + * Smack requires early initialization in order to label 2515 + * all processes and objects when they are created. 2516 + */ 2517 + security_initcall(smack_init); 2518 +
+981
security/smack/smackfs.c
··· 1 + /* 2 + * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation, version 2. 7 + * 8 + * Authors: 9 + * Casey Schaufler <casey@schaufler-ca.com> 10 + * Ahmed S. Darwish <darwish.07@gmail.com> 11 + * 12 + * Special thanks to the authors of selinuxfs. 13 + * 14 + * Karl MacMillan <kmacmillan@tresys.com> 15 + * James Morris <jmorris@redhat.com> 16 + * 17 + */ 18 + 19 + #include <linux/kernel.h> 20 + #include <linux/vmalloc.h> 21 + #include <linux/security.h> 22 + #include <linux/mutex.h> 23 + #include <net/netlabel.h> 24 + #include <net/cipso_ipv4.h> 25 + #include <linux/seq_file.h> 26 + #include <linux/ctype.h> 27 + #include "smack.h" 28 + 29 + /* 30 + * smackfs pseudo filesystem. 31 + */ 32 + 33 + enum smk_inos { 34 + SMK_ROOT_INO = 2, 35 + SMK_LOAD = 3, /* load policy */ 36 + SMK_CIPSO = 4, /* load label -> CIPSO mapping */ 37 + SMK_DOI = 5, /* CIPSO DOI */ 38 + SMK_DIRECT = 6, /* CIPSO level indicating direct label */ 39 + SMK_AMBIENT = 7, /* internet ambient label */ 40 + SMK_NLTYPE = 8, /* label scheme to use by default */ 41 + }; 42 + 43 + /* 44 + * List locks 45 + */ 46 + static DEFINE_MUTEX(smack_list_lock); 47 + static DEFINE_MUTEX(smack_cipso_lock); 48 + 49 + /* 50 + * This is the "ambient" label for network traffic. 51 + * If it isn't somehow marked, use this. 52 + * It can be reset via smackfs/ambient 53 + */ 54 + char *smack_net_ambient = smack_known_floor.smk_known; 55 + 56 + /* 57 + * This is the default packet marking scheme for network traffic. 58 + * It can be reset via smackfs/nltype 59 + */ 60 + int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4; 61 + 62 + /* 63 + * This is the level in a CIPSO header that indicates a 64 + * smack label is contained directly in the category set. 65 + * It can be reset via smackfs/direct 66 + */ 67 + int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; 68 + 69 + static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 70 + struct smk_list_entry *smack_list; 71 + 72 + #define SEQ_READ_FINISHED 1 73 + 74 + /* 75 + * Disable concurrent writing open() operations 76 + */ 77 + static struct semaphore smack_write_sem; 78 + 79 + /* 80 + * Values for parsing cipso rules 81 + * SMK_DIGITLEN: Length of a digit field in a rule. 82 + * SMK_CIPSOMEN: Minimum possible cipso rule length. 83 + */ 84 + #define SMK_DIGITLEN 4 85 + #define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN) 86 + 87 + /* 88 + * Seq_file read operations for /smack/load 89 + */ 90 + 91 + static void *load_seq_start(struct seq_file *s, loff_t *pos) 92 + { 93 + if (*pos == SEQ_READ_FINISHED) 94 + return NULL; 95 + 96 + return smack_list; 97 + } 98 + 99 + static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) 100 + { 101 + struct smk_list_entry *skp = ((struct smk_list_entry *) v)->smk_next; 102 + 103 + if (skp == NULL) 104 + *pos = SEQ_READ_FINISHED; 105 + 106 + return skp; 107 + } 108 + 109 + static int load_seq_show(struct seq_file *s, void *v) 110 + { 111 + struct smk_list_entry *slp = (struct smk_list_entry *) v; 112 + struct smack_rule *srp = &slp->smk_rule; 113 + 114 + seq_printf(s, "%s %s", (char *)srp->smk_subject, 115 + (char *)srp->smk_object); 116 + 117 + seq_putc(s, ' '); 118 + 119 + if (srp->smk_access & MAY_READ) 120 + seq_putc(s, 'r'); 121 + if (srp->smk_access & MAY_WRITE) 122 + seq_putc(s, 'w'); 123 + if (srp->smk_access & MAY_EXEC) 124 + seq_putc(s, 'x'); 125 + if (srp->smk_access & MAY_APPEND) 126 + seq_putc(s, 'a'); 127 + if (srp->smk_access == 0) 128 + seq_putc(s, '-'); 129 + 130 + seq_putc(s, '\n'); 131 + 132 + return 0; 133 + } 134 + 135 + static void load_seq_stop(struct seq_file *s, void *v) 136 + { 137 + /* No-op */ 138 + } 139 + 140 + static struct seq_operations load_seq_ops = { 141 + .start = load_seq_start, 142 + .next = load_seq_next, 143 + .show = load_seq_show, 144 + .stop = load_seq_stop, 145 + }; 146 + 147 + /** 148 + * smk_open_load - open() for /smack/load 149 + * @inode: inode structure representing file 150 + * @file: "load" file pointer 151 + * 152 + * For reading, use load_seq_* seq_file reading operations. 153 + */ 154 + static int smk_open_load(struct inode *inode, struct file *file) 155 + { 156 + if ((file->f_flags & O_ACCMODE) == O_RDONLY) 157 + return seq_open(file, &load_seq_ops); 158 + 159 + if (down_interruptible(&smack_write_sem)) 160 + return -ERESTARTSYS; 161 + 162 + return 0; 163 + } 164 + 165 + /** 166 + * smk_release_load - release() for /smack/load 167 + * @inode: inode structure representing file 168 + * @file: "load" file pointer 169 + * 170 + * For a reading session, use the seq_file release 171 + * implementation. 172 + * Otherwise, we are at the end of a writing session so 173 + * clean everything up. 174 + */ 175 + static int smk_release_load(struct inode *inode, struct file *file) 176 + { 177 + if ((file->f_flags & O_ACCMODE) == O_RDONLY) 178 + return seq_release(inode, file); 179 + 180 + up(&smack_write_sem); 181 + return 0; 182 + } 183 + 184 + /** 185 + * smk_set_access - add a rule to the rule list 186 + * @srp: the new rule to add 187 + * 188 + * Looks through the current subject/object/access list for 189 + * the subject/object pair and replaces the access that was 190 + * there. If the pair isn't found add it with the specified 191 + * access. 192 + */ 193 + static void smk_set_access(struct smack_rule *srp) 194 + { 195 + struct smk_list_entry *sp; 196 + struct smk_list_entry *newp; 197 + 198 + mutex_lock(&smack_list_lock); 199 + 200 + for (sp = smack_list; sp != NULL; sp = sp->smk_next) 201 + if (sp->smk_rule.smk_subject == srp->smk_subject && 202 + sp->smk_rule.smk_object == srp->smk_object) { 203 + sp->smk_rule.smk_access = srp->smk_access; 204 + break; 205 + } 206 + 207 + if (sp == NULL) { 208 + newp = kzalloc(sizeof(struct smk_list_entry), GFP_KERNEL); 209 + newp->smk_rule = *srp; 210 + newp->smk_next = smack_list; 211 + smack_list = newp; 212 + } 213 + 214 + mutex_unlock(&smack_list_lock); 215 + 216 + return; 217 + } 218 + 219 + /** 220 + * smk_write_load - write() for /smack/load 221 + * @filp: file pointer, not actually used 222 + * @buf: where to get the data from 223 + * @count: bytes sent 224 + * @ppos: where to start - must be 0 225 + * 226 + * Get one smack access rule from above. 227 + * The format is exactly: 228 + * char subject[SMK_LABELLEN] 229 + * char object[SMK_LABELLEN] 230 + * char access[SMK_ACCESSKINDS] 231 + * 232 + * Anything following is commentary and ignored. 233 + * 234 + * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes. 235 + */ 236 + #define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS) 237 + 238 + static ssize_t smk_write_load(struct file *file, const char __user *buf, 239 + size_t count, loff_t *ppos) 240 + { 241 + struct smack_rule rule; 242 + char *data; 243 + int rc = -EINVAL; 244 + 245 + /* 246 + * Must have privilege. 247 + * No partial writes. 248 + * Enough data must be present. 249 + */ 250 + if (!capable(CAP_MAC_ADMIN)) 251 + return -EPERM; 252 + if (*ppos != 0) 253 + return -EINVAL; 254 + if (count < MINIMUM_LOAD) 255 + return -EINVAL; 256 + 257 + data = kzalloc(count, GFP_KERNEL); 258 + if (data == NULL) 259 + return -ENOMEM; 260 + 261 + if (copy_from_user(data, buf, count) != 0) { 262 + rc = -EFAULT; 263 + goto out; 264 + } 265 + 266 + rule.smk_subject = smk_import(data, 0); 267 + if (rule.smk_subject == NULL) 268 + goto out; 269 + 270 + rule.smk_object = smk_import(data + SMK_LABELLEN, 0); 271 + if (rule.smk_object == NULL) 272 + goto out; 273 + 274 + rule.smk_access = 0; 275 + 276 + switch (data[SMK_LABELLEN + SMK_LABELLEN]) { 277 + case '-': 278 + break; 279 + case 'r': 280 + case 'R': 281 + rule.smk_access |= MAY_READ; 282 + break; 283 + default: 284 + goto out; 285 + } 286 + 287 + switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) { 288 + case '-': 289 + break; 290 + case 'w': 291 + case 'W': 292 + rule.smk_access |= MAY_WRITE; 293 + break; 294 + default: 295 + goto out; 296 + } 297 + 298 + switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) { 299 + case '-': 300 + break; 301 + case 'x': 302 + case 'X': 303 + rule.smk_access |= MAY_EXEC; 304 + break; 305 + default: 306 + goto out; 307 + } 308 + 309 + switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) { 310 + case '-': 311 + break; 312 + case 'a': 313 + case 'A': 314 + rule.smk_access |= MAY_READ; 315 + break; 316 + default: 317 + goto out; 318 + } 319 + 320 + smk_set_access(&rule); 321 + rc = count; 322 + 323 + out: 324 + kfree(data); 325 + return rc; 326 + } 327 + 328 + static const struct file_operations smk_load_ops = { 329 + .open = smk_open_load, 330 + .read = seq_read, 331 + .llseek = seq_lseek, 332 + .write = smk_write_load, 333 + .release = smk_release_load, 334 + }; 335 + 336 + /** 337 + * smk_cipso_doi - initialize the CIPSO domain 338 + */ 339 + void smk_cipso_doi(void) 340 + { 341 + int rc; 342 + struct cipso_v4_doi *doip; 343 + struct netlbl_audit audit_info; 344 + 345 + rc = netlbl_cfg_map_del(NULL, &audit_info); 346 + if (rc != 0) 347 + printk(KERN_WARNING "%s:%d remove rc = %d\n", 348 + __func__, __LINE__, rc); 349 + 350 + doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL); 351 + if (doip == NULL) 352 + panic("smack: Failed to initialize cipso DOI.\n"); 353 + doip->map.std = NULL; 354 + doip->doi = smk_cipso_doi_value; 355 + doip->type = CIPSO_V4_MAP_PASS; 356 + doip->tags[0] = CIPSO_V4_TAG_RBITMAP; 357 + for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++) 358 + doip->tags[rc] = CIPSO_V4_TAG_INVALID; 359 + 360 + rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info); 361 + if (rc != 0) 362 + printk(KERN_WARNING "%s:%d add rc = %d\n", 363 + __func__, __LINE__, rc); 364 + } 365 + 366 + /* 367 + * Seq_file read operations for /smack/cipso 368 + */ 369 + 370 + static void *cipso_seq_start(struct seq_file *s, loff_t *pos) 371 + { 372 + if (*pos == SEQ_READ_FINISHED) 373 + return NULL; 374 + 375 + return smack_known; 376 + } 377 + 378 + static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos) 379 + { 380 + struct smack_known *skp = ((struct smack_known *) v)->smk_next; 381 + 382 + /* 383 + * Omit labels with no associated cipso value 384 + */ 385 + while (skp != NULL && !skp->smk_cipso) 386 + skp = skp->smk_next; 387 + 388 + if (skp == NULL) 389 + *pos = SEQ_READ_FINISHED; 390 + 391 + return skp; 392 + } 393 + 394 + /* 395 + * Print cipso labels in format: 396 + * label level[/cat[,cat]] 397 + */ 398 + static int cipso_seq_show(struct seq_file *s, void *v) 399 + { 400 + struct smack_known *skp = (struct smack_known *) v; 401 + struct smack_cipso *scp = skp->smk_cipso; 402 + char *cbp; 403 + char sep = '/'; 404 + int cat = 1; 405 + int i; 406 + unsigned char m; 407 + 408 + if (scp == NULL) 409 + return 0; 410 + 411 + seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level); 412 + 413 + cbp = scp->smk_catset; 414 + for (i = 0; i < SMK_LABELLEN; i++) 415 + for (m = 0x80; m != 0; m >>= 1) { 416 + if (m & cbp[i]) { 417 + seq_printf(s, "%c%d", sep, cat); 418 + sep = ','; 419 + } 420 + cat++; 421 + } 422 + 423 + seq_putc(s, '\n'); 424 + 425 + return 0; 426 + } 427 + 428 + static void cipso_seq_stop(struct seq_file *s, void *v) 429 + { 430 + /* No-op */ 431 + } 432 + 433 + static struct seq_operations cipso_seq_ops = { 434 + .start = cipso_seq_start, 435 + .stop = cipso_seq_stop, 436 + .next = cipso_seq_next, 437 + .show = cipso_seq_show, 438 + }; 439 + 440 + /** 441 + * smk_open_cipso - open() for /smack/cipso 442 + * @inode: inode structure representing file 443 + * @file: "cipso" file pointer 444 + * 445 + * Connect our cipso_seq_* operations with /smack/cipso 446 + * file_operations 447 + */ 448 + static int smk_open_cipso(struct inode *inode, struct file *file) 449 + { 450 + return seq_open(file, &cipso_seq_ops); 451 + } 452 + 453 + /** 454 + * smk_write_cipso - write() for /smack/cipso 455 + * @filp: file pointer, not actually used 456 + * @buf: where to get the data from 457 + * @count: bytes sent 458 + * @ppos: where to start 459 + * 460 + * Accepts only one cipso rule per write call. 461 + * Returns number of bytes written or error code, as appropriate 462 + */ 463 + static ssize_t smk_write_cipso(struct file *file, const char __user *buf, 464 + size_t count, loff_t *ppos) 465 + { 466 + struct smack_known *skp; 467 + struct smack_cipso *scp = NULL; 468 + char mapcatset[SMK_LABELLEN]; 469 + int maplevel; 470 + int cat; 471 + int catlen; 472 + ssize_t rc = -EINVAL; 473 + char *data = NULL; 474 + char *rule; 475 + int ret; 476 + int i; 477 + 478 + /* 479 + * Must have privilege. 480 + * No partial writes. 481 + * Enough data must be present. 482 + */ 483 + if (!capable(CAP_MAC_ADMIN)) 484 + return -EPERM; 485 + if (*ppos != 0) 486 + return -EINVAL; 487 + if (count <= SMK_CIPSOMIN) 488 + return -EINVAL; 489 + 490 + data = kzalloc(count + 1, GFP_KERNEL); 491 + if (data == NULL) 492 + return -ENOMEM; 493 + 494 + if (copy_from_user(data, buf, count) != 0) { 495 + rc = -EFAULT; 496 + goto unlockedout; 497 + } 498 + 499 + data[count] = '\0'; 500 + rule = data; 501 + /* 502 + * Only allow one writer at a time. Writes should be 503 + * quite rare and small in any case. 504 + */ 505 + mutex_lock(&smack_cipso_lock); 506 + 507 + skp = smk_import_entry(rule, 0); 508 + if (skp == NULL) 509 + goto out; 510 + 511 + rule += SMK_LABELLEN;; 512 + ret = sscanf(rule, "%d", &maplevel); 513 + if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) 514 + goto out; 515 + 516 + rule += SMK_DIGITLEN; 517 + ret = sscanf(rule, "%d", &catlen); 518 + if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) 519 + goto out; 520 + 521 + if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) 522 + goto out; 523 + 524 + memset(mapcatset, 0, sizeof(mapcatset)); 525 + 526 + for (i = 0; i < catlen; i++) { 527 + rule += SMK_DIGITLEN; 528 + ret = sscanf(rule, "%d", &cat); 529 + if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL) 530 + goto out; 531 + 532 + smack_catset_bit(cat, mapcatset); 533 + } 534 + 535 + if (skp->smk_cipso == NULL) { 536 + scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL); 537 + if (scp == NULL) { 538 + rc = -ENOMEM; 539 + goto out; 540 + } 541 + } 542 + 543 + spin_lock_bh(&skp->smk_cipsolock); 544 + 545 + if (scp == NULL) 546 + scp = skp->smk_cipso; 547 + else 548 + skp->smk_cipso = scp; 549 + 550 + scp->smk_level = maplevel; 551 + memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset)); 552 + 553 + spin_unlock_bh(&skp->smk_cipsolock); 554 + 555 + rc = count; 556 + out: 557 + mutex_unlock(&smack_cipso_lock); 558 + unlockedout: 559 + kfree(data); 560 + return rc; 561 + } 562 + 563 + static const struct file_operations smk_cipso_ops = { 564 + .open = smk_open_cipso, 565 + .read = seq_read, 566 + .llseek = seq_lseek, 567 + .write = smk_write_cipso, 568 + .release = seq_release, 569 + }; 570 + 571 + /** 572 + * smk_read_doi - read() for /smack/doi 573 + * @filp: file pointer, not actually used 574 + * @buf: where to put the result 575 + * @count: maximum to send along 576 + * @ppos: where to start 577 + * 578 + * Returns number of bytes read or error code, as appropriate 579 + */ 580 + static ssize_t smk_read_doi(struct file *filp, char __user *buf, 581 + size_t count, loff_t *ppos) 582 + { 583 + char temp[80]; 584 + ssize_t rc; 585 + 586 + if (*ppos != 0) 587 + return 0; 588 + 589 + sprintf(temp, "%d", smk_cipso_doi_value); 590 + rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); 591 + 592 + return rc; 593 + } 594 + 595 + /** 596 + * smk_write_doi - write() for /smack/doi 597 + * @filp: file pointer, not actually used 598 + * @buf: where to get the data from 599 + * @count: bytes sent 600 + * @ppos: where to start 601 + * 602 + * Returns number of bytes written or error code, as appropriate 603 + */ 604 + static ssize_t smk_write_doi(struct file *file, const char __user *buf, 605 + size_t count, loff_t *ppos) 606 + { 607 + char temp[80]; 608 + int i; 609 + 610 + if (!capable(CAP_MAC_ADMIN)) 611 + return -EPERM; 612 + 613 + if (count >= sizeof(temp) || count == 0) 614 + return -EINVAL; 615 + 616 + if (copy_from_user(temp, buf, count) != 0) 617 + return -EFAULT; 618 + 619 + temp[count] = '\0'; 620 + 621 + if (sscanf(temp, "%d", &i) != 1) 622 + return -EINVAL; 623 + 624 + smk_cipso_doi_value = i; 625 + 626 + smk_cipso_doi(); 627 + 628 + return count; 629 + } 630 + 631 + static const struct file_operations smk_doi_ops = { 632 + .read = smk_read_doi, 633 + .write = smk_write_doi, 634 + }; 635 + 636 + /** 637 + * smk_read_direct - read() for /smack/direct 638 + * @filp: file pointer, not actually used 639 + * @buf: where to put the result 640 + * @count: maximum to send along 641 + * @ppos: where to start 642 + * 643 + * Returns number of bytes read or error code, as appropriate 644 + */ 645 + static ssize_t smk_read_direct(struct file *filp, char __user *buf, 646 + size_t count, loff_t *ppos) 647 + { 648 + char temp[80]; 649 + ssize_t rc; 650 + 651 + if (*ppos != 0) 652 + return 0; 653 + 654 + sprintf(temp, "%d", smack_cipso_direct); 655 + rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); 656 + 657 + return rc; 658 + } 659 + 660 + /** 661 + * smk_write_direct - write() for /smack/direct 662 + * @filp: file pointer, not actually used 663 + * @buf: where to get the data from 664 + * @count: bytes sent 665 + * @ppos: where to start 666 + * 667 + * Returns number of bytes written or error code, as appropriate 668 + */ 669 + static ssize_t smk_write_direct(struct file *file, const char __user *buf, 670 + size_t count, loff_t *ppos) 671 + { 672 + char temp[80]; 673 + int i; 674 + 675 + if (!capable(CAP_MAC_ADMIN)) 676 + return -EPERM; 677 + 678 + if (count >= sizeof(temp) || count == 0) 679 + return -EINVAL; 680 + 681 + if (copy_from_user(temp, buf, count) != 0) 682 + return -EFAULT; 683 + 684 + temp[count] = '\0'; 685 + 686 + if (sscanf(temp, "%d", &i) != 1) 687 + return -EINVAL; 688 + 689 + smack_cipso_direct = i; 690 + 691 + return count; 692 + } 693 + 694 + static const struct file_operations smk_direct_ops = { 695 + .read = smk_read_direct, 696 + .write = smk_write_direct, 697 + }; 698 + 699 + /** 700 + * smk_read_ambient - read() for /smack/ambient 701 + * @filp: file pointer, not actually used 702 + * @buf: where to put the result 703 + * @cn: maximum to send along 704 + * @ppos: where to start 705 + * 706 + * Returns number of bytes read or error code, as appropriate 707 + */ 708 + static ssize_t smk_read_ambient(struct file *filp, char __user *buf, 709 + size_t cn, loff_t *ppos) 710 + { 711 + ssize_t rc; 712 + char out[SMK_LABELLEN]; 713 + int asize; 714 + 715 + if (*ppos != 0) 716 + return 0; 717 + /* 718 + * Being careful to avoid a problem in the case where 719 + * smack_net_ambient gets changed in midstream. 720 + * Since smack_net_ambient is always set with a value 721 + * from the label list, including initially, and those 722 + * never get freed, the worst case is that the pointer 723 + * gets changed just after this strncpy, in which case 724 + * the value passed up is incorrect. Locking around 725 + * smack_net_ambient wouldn't be any better than this 726 + * copy scheme as by the time the caller got to look 727 + * at the ambient value it would have cleared the lock 728 + * and been changed. 729 + */ 730 + strncpy(out, smack_net_ambient, SMK_LABELLEN); 731 + asize = strlen(out) + 1; 732 + 733 + if (cn < asize) 734 + return -EINVAL; 735 + 736 + rc = simple_read_from_buffer(buf, cn, ppos, out, asize); 737 + 738 + return rc; 739 + } 740 + 741 + /** 742 + * smk_write_ambient - write() for /smack/ambient 743 + * @filp: file pointer, not actually used 744 + * @buf: where to get the data from 745 + * @count: bytes sent 746 + * @ppos: where to start 747 + * 748 + * Returns number of bytes written or error code, as appropriate 749 + */ 750 + static ssize_t smk_write_ambient(struct file *file, const char __user *buf, 751 + size_t count, loff_t *ppos) 752 + { 753 + char in[SMK_LABELLEN]; 754 + char *smack; 755 + 756 + if (!capable(CAP_MAC_ADMIN)) 757 + return -EPERM; 758 + 759 + if (count >= SMK_LABELLEN) 760 + return -EINVAL; 761 + 762 + if (copy_from_user(in, buf, count) != 0) 763 + return -EFAULT; 764 + 765 + smack = smk_import(in, count); 766 + if (smack == NULL) 767 + return -EINVAL; 768 + 769 + smack_net_ambient = smack; 770 + 771 + return count; 772 + } 773 + 774 + static const struct file_operations smk_ambient_ops = { 775 + .read = smk_read_ambient, 776 + .write = smk_write_ambient, 777 + }; 778 + 779 + struct option_names { 780 + int o_number; 781 + char *o_name; 782 + char *o_alias; 783 + }; 784 + 785 + static struct option_names netlbl_choices[] = { 786 + { NETLBL_NLTYPE_RIPSO, 787 + NETLBL_NLTYPE_RIPSO_NAME, "ripso" }, 788 + { NETLBL_NLTYPE_CIPSOV4, 789 + NETLBL_NLTYPE_CIPSOV4_NAME, "cipsov4" }, 790 + { NETLBL_NLTYPE_CIPSOV4, 791 + NETLBL_NLTYPE_CIPSOV4_NAME, "cipso" }, 792 + { NETLBL_NLTYPE_CIPSOV6, 793 + NETLBL_NLTYPE_CIPSOV6_NAME, "cipsov6" }, 794 + { NETLBL_NLTYPE_UNLABELED, 795 + NETLBL_NLTYPE_UNLABELED_NAME, "unlabeled" }, 796 + }; 797 + 798 + /** 799 + * smk_read_nltype - read() for /smack/nltype 800 + * @filp: file pointer, not actually used 801 + * @buf: where to put the result 802 + * @count: maximum to send along 803 + * @ppos: where to start 804 + * 805 + * Returns number of bytes read or error code, as appropriate 806 + */ 807 + static ssize_t smk_read_nltype(struct file *filp, char __user *buf, 808 + size_t count, loff_t *ppos) 809 + { 810 + char bound[40]; 811 + ssize_t rc; 812 + int i; 813 + 814 + if (count < SMK_LABELLEN) 815 + return -EINVAL; 816 + 817 + if (*ppos != 0) 818 + return 0; 819 + 820 + sprintf(bound, "unknown"); 821 + 822 + for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++) 823 + if (smack_net_nltype == netlbl_choices[i].o_number) { 824 + sprintf(bound, "%s", netlbl_choices[i].o_name); 825 + break; 826 + } 827 + 828 + rc = simple_read_from_buffer(buf, count, ppos, bound, strlen(bound)); 829 + 830 + return rc; 831 + } 832 + 833 + /** 834 + * smk_write_nltype - write() for /smack/nltype 835 + * @filp: file pointer, not actually used 836 + * @buf: where to get the data from 837 + * @count: bytes sent 838 + * @ppos: where to start 839 + * 840 + * Returns number of bytes written or error code, as appropriate 841 + */ 842 + static ssize_t smk_write_nltype(struct file *file, const char __user *buf, 843 + size_t count, loff_t *ppos) 844 + { 845 + char bound[40]; 846 + char *cp; 847 + int i; 848 + 849 + if (!capable(CAP_MAC_ADMIN)) 850 + return -EPERM; 851 + 852 + if (count >= 40) 853 + return -EINVAL; 854 + 855 + if (copy_from_user(bound, buf, count) != 0) 856 + return -EFAULT; 857 + 858 + bound[count] = '\0'; 859 + cp = strchr(bound, ' '); 860 + if (cp != NULL) 861 + *cp = '\0'; 862 + cp = strchr(bound, '\n'); 863 + if (cp != NULL) 864 + *cp = '\0'; 865 + 866 + for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++) 867 + if (strcmp(bound, netlbl_choices[i].o_name) == 0 || 868 + strcmp(bound, netlbl_choices[i].o_alias) == 0) { 869 + smack_net_nltype = netlbl_choices[i].o_number; 870 + return count; 871 + } 872 + /* 873 + * Not a valid choice. 874 + */ 875 + return -EINVAL; 876 + } 877 + 878 + static const struct file_operations smk_nltype_ops = { 879 + .read = smk_read_nltype, 880 + .write = smk_write_nltype, 881 + }; 882 + 883 + /** 884 + * smk_fill_super - fill the /smackfs superblock 885 + * @sb: the empty superblock 886 + * @data: unused 887 + * @silent: unused 888 + * 889 + * Fill in the well known entries for /smack 890 + * 891 + * Returns 0 on success, an error code on failure 892 + */ 893 + static int smk_fill_super(struct super_block *sb, void *data, int silent) 894 + { 895 + int rc; 896 + struct inode *root_inode; 897 + 898 + static struct tree_descr smack_files[] = { 899 + [SMK_LOAD] = 900 + {"load", &smk_load_ops, S_IRUGO|S_IWUSR}, 901 + [SMK_CIPSO] = 902 + {"cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR}, 903 + [SMK_DOI] = 904 + {"doi", &smk_doi_ops, S_IRUGO|S_IWUSR}, 905 + [SMK_DIRECT] = 906 + {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR}, 907 + [SMK_AMBIENT] = 908 + {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, 909 + [SMK_NLTYPE] = 910 + {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR}, 911 + /* last one */ {""} 912 + }; 913 + 914 + rc = simple_fill_super(sb, SMACK_MAGIC, smack_files); 915 + if (rc != 0) { 916 + printk(KERN_ERR "%s failed %d while creating inodes\n", 917 + __func__, rc); 918 + return rc; 919 + } 920 + 921 + root_inode = sb->s_root->d_inode; 922 + root_inode->i_security = new_inode_smack(smack_known_floor.smk_known); 923 + 924 + return 0; 925 + } 926 + 927 + /** 928 + * smk_get_sb - get the smackfs superblock 929 + * @fs_type: passed along without comment 930 + * @flags: passed along without comment 931 + * @dev_name: passed along without comment 932 + * @data: passed along without comment 933 + * @mnt: passed along without comment 934 + * 935 + * Just passes everything along. 936 + * 937 + * Returns what the lower level code does. 938 + */ 939 + static int smk_get_sb(struct file_system_type *fs_type, 940 + int flags, const char *dev_name, void *data, 941 + struct vfsmount *mnt) 942 + { 943 + return get_sb_single(fs_type, flags, data, smk_fill_super, mnt); 944 + } 945 + 946 + static struct file_system_type smk_fs_type = { 947 + .name = "smackfs", 948 + .get_sb = smk_get_sb, 949 + .kill_sb = kill_litter_super, 950 + }; 951 + 952 + static struct vfsmount *smackfs_mount; 953 + 954 + /** 955 + * init_smk_fs - get the smackfs superblock 956 + * 957 + * register the smackfs 958 + * 959 + * Returns 0 unless the registration fails. 960 + */ 961 + static int __init init_smk_fs(void) 962 + { 963 + int err; 964 + 965 + err = register_filesystem(&smk_fs_type); 966 + if (!err) { 967 + smackfs_mount = kern_mount(&smk_fs_type); 968 + if (IS_ERR(smackfs_mount)) { 969 + printk(KERN_ERR "smackfs: could not mount!\n"); 970 + err = PTR_ERR(smackfs_mount); 971 + smackfs_mount = NULL; 972 + } 973 + } 974 + 975 + sema_init(&smack_write_sem, 1); 976 + smk_cipso_doi(); 977 + 978 + return err; 979 + } 980 + 981 + __initcall(init_smk_fs);