| .. | .. |
|---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-only */ |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> |
|---|
| 3 | 4 | * |
|---|
| 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 | 5 | * Author: |
|---|
| 9 | 6 | * Casey Schaufler <casey@schaufler-ca.com> |
|---|
| 10 | | - * |
|---|
| 11 | 7 | */ |
|---|
| 12 | 8 | |
|---|
| 13 | 9 | #ifndef _SECURITY_SMACK_H |
|---|
| .. | .. |
|---|
| 24 | 20 | #include <linux/list.h> |
|---|
| 25 | 21 | #include <linux/rculist.h> |
|---|
| 26 | 22 | #include <linux/lsm_audit.h> |
|---|
| 23 | +#include <linux/msg.h> |
|---|
| 27 | 24 | |
|---|
| 28 | 25 | /* |
|---|
| 29 | 26 | * Use IPv6 port labeling if IPv6 is enabled and secmarks |
|---|
| .. | .. |
|---|
| 103 | 100 | struct smack_known *smk_out; /* outbound label */ |
|---|
| 104 | 101 | struct smack_known *smk_in; /* inbound label */ |
|---|
| 105 | 102 | struct smack_known *smk_packet; /* TCP peer label */ |
|---|
| 103 | + int smk_state; /* netlabel socket states */ |
|---|
| 106 | 104 | }; |
|---|
| 105 | +#define SMK_NETLBL_UNSET 0 |
|---|
| 106 | +#define SMK_NETLBL_UNLABELED 1 |
|---|
| 107 | +#define SMK_NETLBL_LABELED 2 |
|---|
| 108 | +#define SMK_NETLBL_REQSKB 3 |
|---|
| 107 | 109 | |
|---|
| 108 | 110 | /* |
|---|
| 109 | 111 | * Inode smack data |
|---|
| .. | .. |
|---|
| 112 | 114 | struct smack_known *smk_inode; /* label of the fso */ |
|---|
| 113 | 115 | struct smack_known *smk_task; /* label of the task */ |
|---|
| 114 | 116 | struct smack_known *smk_mmap; /* label of the mmap domain */ |
|---|
| 115 | | - struct mutex smk_lock; /* initialization lock */ |
|---|
| 116 | 117 | int smk_flags; /* smack inode flags */ |
|---|
| 117 | | - struct rcu_head smk_rcu; /* for freeing inode_smack */ |
|---|
| 118 | 118 | }; |
|---|
| 119 | 119 | |
|---|
| 120 | 120 | struct task_smack { |
|---|
| 121 | 121 | struct smack_known *smk_task; /* label for access control */ |
|---|
| 122 | 122 | struct smack_known *smk_forked; /* label when forked */ |
|---|
| 123 | + struct smack_known *smk_transmuted;/* label when transmuted */ |
|---|
| 123 | 124 | struct list_head smk_rules; /* per task access rules */ |
|---|
| 124 | 125 | struct mutex smk_rules_lock; /* lock for the rules */ |
|---|
| 125 | 126 | struct list_head smk_relabel; /* transit allowed labels */ |
|---|
| .. | .. |
|---|
| 151 | 152 | struct smack_known *smk_label; /* label */ |
|---|
| 152 | 153 | }; |
|---|
| 153 | 154 | |
|---|
| 154 | | -#if IS_ENABLED(CONFIG_IPV6) |
|---|
| 155 | 155 | /* |
|---|
| 156 | 156 | * An entry in the table identifying IPv6 hosts. |
|---|
| 157 | 157 | */ |
|---|
| .. | .. |
|---|
| 162 | 162 | int smk_masks; /* mask size */ |
|---|
| 163 | 163 | struct smack_known *smk_label; /* label */ |
|---|
| 164 | 164 | }; |
|---|
| 165 | | -#endif /* CONFIG_IPV6 */ |
|---|
| 166 | 165 | |
|---|
| 167 | | -#ifdef SMACK_IPV6_PORT_LABELING |
|---|
| 168 | 166 | /* |
|---|
| 169 | 167 | * An entry in the table identifying ports. |
|---|
| 170 | 168 | */ |
|---|
| .. | .. |
|---|
| 177 | 175 | short smk_sock_type; /* Socket type */ |
|---|
| 178 | 176 | short smk_can_reuse; |
|---|
| 179 | 177 | }; |
|---|
| 180 | | -#endif /* SMACK_IPV6_PORT_LABELING */ |
|---|
| 181 | 178 | |
|---|
| 182 | 179 | struct smack_known_list_elem { |
|---|
| 183 | 180 | struct list_head list; |
|---|
| .. | .. |
|---|
| 195 | 192 | |
|---|
| 196 | 193 | enum { |
|---|
| 197 | 194 | Opt_error = -1, |
|---|
| 198 | | - Opt_fsdefault = 1, |
|---|
| 199 | | - Opt_fsfloor = 2, |
|---|
| 200 | | - Opt_fshat = 3, |
|---|
| 201 | | - Opt_fsroot = 4, |
|---|
| 202 | | - Opt_fstransmute = 5, |
|---|
| 195 | + Opt_fsdefault = 0, |
|---|
| 196 | + Opt_fsfloor = 1, |
|---|
| 197 | + Opt_fshat = 2, |
|---|
| 198 | + Opt_fsroot = 3, |
|---|
| 199 | + Opt_fstransmute = 4, |
|---|
| 203 | 200 | }; |
|---|
| 204 | | - |
|---|
| 205 | | -/* |
|---|
| 206 | | - * Mount options |
|---|
| 207 | | - */ |
|---|
| 208 | | -#define SMK_FSDEFAULT "smackfsdef=" |
|---|
| 209 | | -#define SMK_FSFLOOR "smackfsfloor=" |
|---|
| 210 | | -#define SMK_FSHAT "smackfshat=" |
|---|
| 211 | | -#define SMK_FSROOT "smackfsroot=" |
|---|
| 212 | | -#define SMK_FSTRANS "smackfstransmute=" |
|---|
| 213 | 201 | |
|---|
| 214 | 202 | #define SMACK_DELETE_OPTION "-DELETE" |
|---|
| 215 | 203 | #define SMACK_CIPSO_OPTION "-CIPSO" |
|---|
| 216 | | - |
|---|
| 217 | | -/* |
|---|
| 218 | | - * How communications on this socket are treated. |
|---|
| 219 | | - * Usually it's determined by the underlying netlabel code |
|---|
| 220 | | - * but there are certain cases, including single label hosts |
|---|
| 221 | | - * and potentially single label interfaces for which the |
|---|
| 222 | | - * treatment can not be known in advance. |
|---|
| 223 | | - * |
|---|
| 224 | | - * The possibility of additional labeling schemes being |
|---|
| 225 | | - * introduced in the future exists as well. |
|---|
| 226 | | - */ |
|---|
| 227 | | -#define SMACK_UNLABELED_SOCKET 0 |
|---|
| 228 | | -#define SMACK_CIPSO_SOCKET 1 |
|---|
| 229 | 204 | |
|---|
| 230 | 205 | /* |
|---|
| 231 | 206 | * CIPSO defaults. |
|---|
| .. | .. |
|---|
| 323 | 298 | bool smack_privileged(int cap); |
|---|
| 324 | 299 | bool smack_privileged_cred(int cap, const struct cred *cred); |
|---|
| 325 | 300 | void smk_destroy_label_list(struct list_head *list); |
|---|
| 301 | +int smack_populate_secattr(struct smack_known *skp); |
|---|
| 326 | 302 | |
|---|
| 327 | 303 | /* |
|---|
| 328 | 304 | * Shared data. |
|---|
| .. | .. |
|---|
| 336 | 312 | extern struct smack_known *smack_unconfined; |
|---|
| 337 | 313 | #endif |
|---|
| 338 | 314 | extern int smack_ptrace_rule; |
|---|
| 315 | +extern struct lsm_blob_sizes smack_blob_sizes; |
|---|
| 339 | 316 | |
|---|
| 340 | 317 | extern struct smack_known smack_known_floor; |
|---|
| 341 | 318 | extern struct smack_known smack_known_hat; |
|---|
| .. | .. |
|---|
| 346 | 323 | extern struct mutex smack_known_lock; |
|---|
| 347 | 324 | extern struct list_head smack_known_list; |
|---|
| 348 | 325 | extern struct list_head smk_net4addr_list; |
|---|
| 349 | | -#if IS_ENABLED(CONFIG_IPV6) |
|---|
| 350 | 326 | extern struct list_head smk_net6addr_list; |
|---|
| 351 | | -#endif /* CONFIG_IPV6 */ |
|---|
| 352 | 327 | |
|---|
| 353 | 328 | extern struct mutex smack_onlycap_lock; |
|---|
| 354 | 329 | extern struct list_head smack_onlycap_list; |
|---|
| 355 | 330 | |
|---|
| 356 | 331 | #define SMACK_HASH_SLOTS 16 |
|---|
| 357 | 332 | extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; |
|---|
| 333 | +extern struct kmem_cache *smack_rule_cache; |
|---|
| 334 | + |
|---|
| 335 | +static inline struct task_smack *smack_cred(const struct cred *cred) |
|---|
| 336 | +{ |
|---|
| 337 | + return cred->security + smack_blob_sizes.lbs_cred; |
|---|
| 338 | +} |
|---|
| 339 | + |
|---|
| 340 | +static inline struct smack_known **smack_file(const struct file *file) |
|---|
| 341 | +{ |
|---|
| 342 | + return (struct smack_known **)(file->f_security + |
|---|
| 343 | + smack_blob_sizes.lbs_file); |
|---|
| 344 | +} |
|---|
| 345 | + |
|---|
| 346 | +static inline struct inode_smack *smack_inode(const struct inode *inode) |
|---|
| 347 | +{ |
|---|
| 348 | + return inode->i_security + smack_blob_sizes.lbs_inode; |
|---|
| 349 | +} |
|---|
| 350 | + |
|---|
| 351 | +static inline struct smack_known **smack_msg_msg(const struct msg_msg *msg) |
|---|
| 352 | +{ |
|---|
| 353 | + return msg->security + smack_blob_sizes.lbs_msg_msg; |
|---|
| 354 | +} |
|---|
| 355 | + |
|---|
| 356 | +static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc) |
|---|
| 357 | +{ |
|---|
| 358 | + return ipc->security + smack_blob_sizes.lbs_ipc; |
|---|
| 359 | +} |
|---|
| 358 | 360 | |
|---|
| 359 | 361 | /* |
|---|
| 360 | 362 | * Is the directory transmuting? |
|---|
| 361 | 363 | */ |
|---|
| 362 | 364 | static inline int smk_inode_transmutable(const struct inode *isp) |
|---|
| 363 | 365 | { |
|---|
| 364 | | - struct inode_smack *sip = isp->i_security; |
|---|
| 366 | + struct inode_smack *sip = smack_inode(isp); |
|---|
| 365 | 367 | return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0; |
|---|
| 366 | 368 | } |
|---|
| 367 | 369 | |
|---|
| .. | .. |
|---|
| 370 | 372 | */ |
|---|
| 371 | 373 | static inline struct smack_known *smk_of_inode(const struct inode *isp) |
|---|
| 372 | 374 | { |
|---|
| 373 | | - struct inode_smack *sip = isp->i_security; |
|---|
| 375 | + struct inode_smack *sip = smack_inode(isp); |
|---|
| 374 | 376 | return sip->smk_inode; |
|---|
| 375 | 377 | } |
|---|
| 376 | 378 | |
|---|
| .. | .. |
|---|
| 382 | 384 | return tsp->smk_task; |
|---|
| 383 | 385 | } |
|---|
| 384 | 386 | |
|---|
| 385 | | -static inline struct smack_known *smk_of_task_struct(const struct task_struct *t) |
|---|
| 387 | +static inline struct smack_known *smk_of_task_struct( |
|---|
| 388 | + const struct task_struct *t) |
|---|
| 386 | 389 | { |
|---|
| 387 | 390 | struct smack_known *skp; |
|---|
| 391 | + const struct cred *cred; |
|---|
| 388 | 392 | |
|---|
| 389 | 393 | rcu_read_lock(); |
|---|
| 390 | | - skp = smk_of_task(__task_cred(t)->security); |
|---|
| 394 | + |
|---|
| 395 | + cred = __task_cred(t); |
|---|
| 396 | + skp = smk_of_task(smack_cred(cred)); |
|---|
| 397 | + |
|---|
| 391 | 398 | rcu_read_unlock(); |
|---|
| 399 | + |
|---|
| 392 | 400 | return skp; |
|---|
| 393 | 401 | } |
|---|
| 394 | 402 | |
|---|
| .. | .. |
|---|
| 405 | 413 | */ |
|---|
| 406 | 414 | static inline struct smack_known *smk_of_current(void) |
|---|
| 407 | 415 | { |
|---|
| 408 | | - return smk_of_task(current_security()); |
|---|
| 416 | + return smk_of_task(smack_cred(current_cred())); |
|---|
| 409 | 417 | } |
|---|
| 410 | 418 | |
|---|
| 411 | 419 | /* |
|---|
| .. | .. |
|---|
| 481 | 489 | } |
|---|
| 482 | 490 | static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, |
|---|
| 483 | 491 | struct dentry *d) |
|---|
| 484 | | -{ |
|---|
| 485 | | -} |
|---|
| 486 | | -static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a, |
|---|
| 487 | | - struct vfsmount *m) |
|---|
| 488 | 492 | { |
|---|
| 489 | 493 | } |
|---|
| 490 | 494 | static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, |
|---|