6d3dc07cbb
Add support for unlabeled network hosts and networks. Relies heavily on Paul Moore's netlabel support. Creates a new entry in /smack called netlabel. Writes to /smack/netlabel take the form: A.B.C.D LABEL or A.B.C.D/N LABEL where A.B.C.D is a network address, N is an integer between 0-32, and LABEL is the Smack label to be used. If /N is omitted /32 is assumed. N designates the netmask for the address. Entries are matched by the most specific address/mask pair. 0.0.0.0/0 will match everything, while 192.168.1.117/32 will match exactly one host. A new system label "@", pronounced "web", is defined. Processes can not be assigned the web label. An address assigned the web label can be written to by any process, and packets coming from a web address can be written to any socket. Use of the web label is a violation of any strict MAC policy, but the web label has been requested many times. The nltype entry has been removed from /smack. It did not work right and the netlabel interface can be used to specify that all hosts be treated as unlabeled. CIPSO labels on incoming packets will be honored, even from designated single label hosts. Single label hosts can only be written to by processes with labels that can write to the label of the host. Packets sent to single label hosts will always be unlabeled. Once added a single label designation cannot be removed, however the label may be changed. The behavior of the ambient label remains unchanged. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Signed-off-by: Paul Moore <paul.moore@hp.com>
243 lines
6.4 KiB
C
243 lines
6.4 KiB
C
/*
|
|
* Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, version 2.
|
|
*
|
|
* Author:
|
|
* Casey Schaufler <casey@schaufler-ca.com>
|
|
*
|
|
*/
|
|
|
|
#ifndef _SECURITY_SMACK_H
|
|
#define _SECURITY_SMACK_H
|
|
|
|
#include <linux/capability.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/security.h>
|
|
#include <linux/in.h>
|
|
#include <net/netlabel.h>
|
|
|
|
/*
|
|
* Why 23? CIPSO is constrained to 30, so a 32 byte buffer is
|
|
* bigger than can be used, and 24 is the next lower multiple
|
|
* of 8, and there are too many issues if there isn't space set
|
|
* aside for the terminating null byte.
|
|
*/
|
|
#define SMK_MAXLEN 23
|
|
#define SMK_LABELLEN (SMK_MAXLEN+1)
|
|
|
|
struct superblock_smack {
|
|
char *smk_root;
|
|
char *smk_floor;
|
|
char *smk_hat;
|
|
char *smk_default;
|
|
int smk_initialized;
|
|
spinlock_t smk_sblock; /* for initialization */
|
|
};
|
|
|
|
struct socket_smack {
|
|
char *smk_out; /* outbound label */
|
|
char *smk_in; /* inbound label */
|
|
int smk_labeled; /* label scheme */
|
|
char smk_packet[SMK_LABELLEN]; /* TCP peer label */
|
|
};
|
|
|
|
/*
|
|
* Inode smack data
|
|
*/
|
|
struct inode_smack {
|
|
char *smk_inode; /* label of the fso */
|
|
struct mutex smk_lock; /* initialization lock */
|
|
int smk_flags; /* smack inode flags */
|
|
};
|
|
|
|
#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
|
|
|
|
/*
|
|
* A label access rule.
|
|
*/
|
|
struct smack_rule {
|
|
char *smk_subject;
|
|
char *smk_object;
|
|
int smk_access;
|
|
};
|
|
|
|
/*
|
|
* An entry in the table of permitted label accesses.
|
|
*/
|
|
struct smk_list_entry {
|
|
struct smk_list_entry *smk_next;
|
|
struct smack_rule smk_rule;
|
|
};
|
|
|
|
/*
|
|
* An entry in the table mapping smack values to
|
|
* CIPSO level/category-set values.
|
|
*/
|
|
struct smack_cipso {
|
|
int smk_level;
|
|
char smk_catset[SMK_LABELLEN];
|
|
};
|
|
|
|
/*
|
|
* An entry in the table identifying hosts.
|
|
*/
|
|
struct smk_netlbladdr {
|
|
struct smk_netlbladdr *smk_next;
|
|
struct sockaddr_in smk_host; /* network address */
|
|
struct in_addr smk_mask; /* network mask */
|
|
char *smk_label; /* label */
|
|
};
|
|
|
|
/*
|
|
* This is the repository for labels seen so that it is
|
|
* not necessary to keep allocating tiny chuncks of memory
|
|
* and so that they can be shared.
|
|
*
|
|
* Labels are never modified in place. Anytime a label
|
|
* is imported (e.g. xattrset on a file) the list is checked
|
|
* for it and it is added if it doesn't exist. The address
|
|
* is passed out in either case. Entries are added, but
|
|
* never deleted.
|
|
*
|
|
* Since labels are hanging around anyway it doesn't
|
|
* hurt to maintain a secid for those awkward situations
|
|
* where kernel components that ought to use LSM independent
|
|
* interfaces don't. The secid should go away when all of
|
|
* these components have been repaired.
|
|
*
|
|
* If there is a cipso value associated with the label it
|
|
* gets stored here, too. This will most likely be rare as
|
|
* the cipso direct mapping in used internally.
|
|
*/
|
|
struct smack_known {
|
|
struct smack_known *smk_next;
|
|
char smk_known[SMK_LABELLEN];
|
|
u32 smk_secid;
|
|
struct smack_cipso *smk_cipso;
|
|
spinlock_t smk_cipsolock; /* for changing cipso map */
|
|
};
|
|
|
|
/*
|
|
* Mount options
|
|
*/
|
|
#define SMK_FSDEFAULT "smackfsdef="
|
|
#define SMK_FSFLOOR "smackfsfloor="
|
|
#define SMK_FSHAT "smackfshat="
|
|
#define SMK_FSROOT "smackfsroot="
|
|
|
|
/*
|
|
* xattr names
|
|
*/
|
|
#define XATTR_SMACK_SUFFIX "SMACK64"
|
|
#define XATTR_SMACK_IPIN "SMACK64IPIN"
|
|
#define XATTR_SMACK_IPOUT "SMACK64IPOUT"
|
|
#define XATTR_NAME_SMACK XATTR_SECURITY_PREFIX XATTR_SMACK_SUFFIX
|
|
#define XATTR_NAME_SMACKIPIN XATTR_SECURITY_PREFIX XATTR_SMACK_IPIN
|
|
#define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT
|
|
|
|
/*
|
|
* How communications on this socket are treated.
|
|
* Usually it's determined by the underlying netlabel code
|
|
* but there are certain cases, including single label hosts
|
|
* and potentially single label interfaces for which the
|
|
* treatment can not be known in advance.
|
|
*
|
|
* The possibility of additional labeling schemes being
|
|
* introduced in the future exists as well.
|
|
*/
|
|
#define SMACK_UNLABELED_SOCKET 0
|
|
#define SMACK_CIPSO_SOCKET 1
|
|
|
|
/*
|
|
* smackfs magic number
|
|
* smackfs macic number
|
|
*/
|
|
#define SMACK_MAGIC 0x43415d53 /* "SMAC" */
|
|
|
|
/*
|
|
* A limit on the number of entries in the lists
|
|
* makes some of the list administration easier.
|
|
*/
|
|
#define SMACK_LIST_MAX 10000
|
|
|
|
/*
|
|
* CIPSO defaults.
|
|
*/
|
|
#define SMACK_CIPSO_DOI_DEFAULT 3 /* Historical */
|
|
#define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */
|
|
#define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */
|
|
#define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */
|
|
#define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */
|
|
#define SMACK_CIPSO_MAXCATNUM 239 /* CIPSO 2.2 standard */
|
|
|
|
/*
|
|
* Just to make the common cases easier to deal with
|
|
*/
|
|
#define MAY_ANY (MAY_READ | MAY_WRITE | MAY_APPEND | MAY_EXEC)
|
|
#define MAY_ANYREAD (MAY_READ | MAY_EXEC)
|
|
#define MAY_ANYWRITE (MAY_WRITE | MAY_APPEND)
|
|
#define MAY_READWRITE (MAY_READ | MAY_WRITE)
|
|
#define MAY_NOT 0
|
|
|
|
/*
|
|
* These functions are in smack_lsm.c
|
|
*/
|
|
struct inode_smack *new_inode_smack(char *);
|
|
|
|
/*
|
|
* These functions are in smack_access.c
|
|
*/
|
|
int smk_access(char *, char *, int);
|
|
int smk_curacc(char *, u32);
|
|
int smack_to_cipso(const char *, struct smack_cipso *);
|
|
void smack_from_cipso(u32, char *, char *);
|
|
char *smack_from_secid(const u32);
|
|
char *smk_import(const char *, int);
|
|
struct smack_known *smk_import_entry(const char *, int);
|
|
u32 smack_to_secid(const char *);
|
|
|
|
/*
|
|
* Shared data.
|
|
*/
|
|
extern int smack_cipso_direct;
|
|
extern char *smack_net_ambient;
|
|
extern char *smack_onlycap;
|
|
|
|
extern struct smack_known *smack_known;
|
|
extern struct smack_known smack_known_floor;
|
|
extern struct smack_known smack_known_hat;
|
|
extern struct smack_known smack_known_huh;
|
|
extern struct smack_known smack_known_invalid;
|
|
extern struct smack_known smack_known_star;
|
|
extern struct smack_known smack_known_web;
|
|
|
|
extern struct smk_list_entry *smack_list;
|
|
extern struct smk_netlbladdr *smack_netlbladdrs;
|
|
extern struct security_operations smack_ops;
|
|
|
|
/*
|
|
* Stricly for CIPSO level manipulation.
|
|
* Set the category bit number in a smack label sized buffer.
|
|
*/
|
|
static inline void smack_catset_bit(int cat, char *catsetp)
|
|
{
|
|
if (cat > SMK_LABELLEN * 8)
|
|
return;
|
|
|
|
catsetp[(cat - 1) / 8] |= 0x80 >> ((cat - 1) % 8);
|
|
}
|
|
|
|
/*
|
|
* Present a pointer to the smack label in an inode blob.
|
|
*/
|
|
static inline char *smk_of_inode(const struct inode *isp)
|
|
{
|
|
struct inode_smack *sip = isp->i_security;
|
|
return sip->smk_inode;
|
|
}
|
|
|
|
#endif /* _SECURITY_SMACK_H */
|