Commit c269497d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'selinux-pr-20220321' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux updates from Paul Moore:
 "We've got a number of SELinux patches queued up, the highlights are:

   - Fixup the security_fs_context_parse_param() LSM hook so it executes
     all of the LSM hook implementations unless a serious error occurs.

     We also correct the SELinux hook implementation so that it returns
     zero on success.

   - In addition to a few SELinux mount option parsing fixes, we
     simplified the parsing by moving it earlier in the process.

     The logic was that it was unlikely an admin/user would use the new
     mount API and not have the policy loaded before passing the SELinux
     options.

   - Properly fixed the LSM/SELinux/SCTP hooks with the addition of the
     security_sctp_assoc_established() hook.

     This work was done in conjunction with the netdev folks and should
     complete the move of the SCTP labeling from the endpoints to the
     associations.

   - Fixed a variety of sparse warnings caused by changes in the "__rcu"
     markings of some core kernel structures.

   - Ensure we access the superblock's LSM security blob using the
     stacking-safe accessors.

   - Added the ability for the kernel to always allow FIOCLEX and
     FIONCLEX if the "ioctl_skip_cloexec" policy capability is
     specified.

   - Various constifications improvements, type casting improvements,
     additional return value checks, and dead code/parameter removal.

   - Documentation fixes"

* tag 'selinux-pr-20220321' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: (23 commits)
  selinux: shorten the policy capability enum names
  docs: fix 'make htmldocs' warning in SCTP.rst
  selinux: allow FIOCLEX and FIONCLEX with policy capability
  selinux: use correct type for context length
  selinux: drop return statement at end of void functions
  security: implement sctp_assoc_established hook in selinux
  security: add sctp_assoc_established hook
  selinux: parse contexts for mount options early
  selinux: various sparse fixes
  selinux: try to use preparsed sid before calling parse_sid()
  selinux: Fix selinux_sb_mnt_opts_compat()
  LSM: general protection fault in legacy_parse_param
  selinux: fix a type cast problem in cred_init_security()
  selinux: drop unused macro
  selinux: simplify cred_init_security
  selinux: do not discard const qualifier in cast
  selinux: drop unused parameter of avtab_insert_node
  selinux: drop cast to same type
  selinux: enclose macro arguments in parenthesis
  selinux: declare name parameter of hash_eval const
  ...
parents 7f313ff0 cdbec3ed
...@@ -15,10 +15,7 @@ For security module support, three SCTP specific hooks have been implemented:: ...@@ -15,10 +15,7 @@ For security module support, three SCTP specific hooks have been implemented::
security_sctp_assoc_request() security_sctp_assoc_request()
security_sctp_bind_connect() security_sctp_bind_connect()
security_sctp_sk_clone() security_sctp_sk_clone()
security_sctp_assoc_established()
Also the following security hook has been utilised::
security_inet_conn_established()
The usage of these hooks are described below with the SELinux implementation The usage of these hooks are described below with the SELinux implementation
described in the `SCTP SELinux Support`_ chapter. described in the `SCTP SELinux Support`_ chapter.
...@@ -122,11 +119,12 @@ calls **sctp_peeloff**\(3). ...@@ -122,11 +119,12 @@ calls **sctp_peeloff**\(3).
@newsk - pointer to new sock structure. @newsk - pointer to new sock structure.
security_inet_conn_established() security_sctp_assoc_established()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Called when a COOKIE ACK is received:: Called when a COOKIE ACK is received, and the peer secid will be
saved into ``@asoc->peer_secid`` for client::
@sk - pointer to sock structure. @asoc - pointer to sctp association structure.
@skb - pointer to skbuff of the COOKIE ACK packet. @skb - pointer to skbuff of the COOKIE ACK packet.
...@@ -134,7 +132,7 @@ Security Hooks used for Association Establishment ...@@ -134,7 +132,7 @@ Security Hooks used for Association Establishment
------------------------------------------------- -------------------------------------------------
The following diagram shows the use of ``security_sctp_bind_connect()``, The following diagram shows the use of ``security_sctp_bind_connect()``,
``security_sctp_assoc_request()``, ``security_inet_conn_established()`` when ``security_sctp_assoc_request()``, ``security_sctp_assoc_established()`` when
establishing an association. establishing an association.
:: ::
...@@ -172,7 +170,7 @@ establishing an association. ...@@ -172,7 +170,7 @@ establishing an association.
<------------------------------------------- COOKIE ACK <------------------------------------------- COOKIE ACK
| | | |
sctp_sf_do_5_1E_ca | sctp_sf_do_5_1E_ca |
Call security_inet_conn_established() | Call security_sctp_assoc_established() |
to set the peer label. | to set the peer label. |
| | | |
| If SCTP_SOCKET_TCP or peeled off | If SCTP_SOCKET_TCP or peeled off
...@@ -198,7 +196,7 @@ hooks with the SELinux specifics expanded below:: ...@@ -198,7 +196,7 @@ hooks with the SELinux specifics expanded below::
security_sctp_assoc_request() security_sctp_assoc_request()
security_sctp_bind_connect() security_sctp_bind_connect()
security_sctp_sk_clone() security_sctp_sk_clone()
security_inet_conn_established() security_sctp_assoc_established()
security_sctp_assoc_request() security_sctp_assoc_request()
...@@ -271,12 +269,12 @@ sockets sid and peer sid to that contained in the ``@asoc sid`` and ...@@ -271,12 +269,12 @@ sockets sid and peer sid to that contained in the ``@asoc sid`` and
@newsk - pointer to new sock structure. @newsk - pointer to new sock structure.
security_inet_conn_established() security_sctp_assoc_established()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Called when a COOKIE ACK is received where it sets the connection's peer sid Called when a COOKIE ACK is received where it sets the connection's peer sid
to that in ``@skb``:: to that in ``@skb``::
@sk - pointer to sock structure. @asoc - pointer to sctp association structure.
@skb - pointer to skbuff of the COOKIE ACK packet. @skb - pointer to skbuff of the COOKIE ACK packet.
......
...@@ -332,6 +332,8 @@ LSM_HOOK(int, 0, sctp_bind_connect, struct sock *sk, int optname, ...@@ -332,6 +332,8 @@ LSM_HOOK(int, 0, sctp_bind_connect, struct sock *sk, int optname,
struct sockaddr *address, int addrlen) struct sockaddr *address, int addrlen)
LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc, LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc,
struct sock *sk, struct sock *newsk) struct sock *sk, struct sock *newsk)
LSM_HOOK(int, 0, sctp_assoc_established, struct sctp_association *asoc,
struct sk_buff *skb)
#endif /* CONFIG_SECURITY_NETWORK */ #endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_INFINIBAND #ifdef CONFIG_SECURITY_INFINIBAND
......
...@@ -1046,6 +1046,11 @@ ...@@ -1046,6 +1046,11 @@
* @asoc pointer to current sctp association structure. * @asoc pointer to current sctp association structure.
* @sk pointer to current sock structure. * @sk pointer to current sock structure.
* @newsk pointer to new sock structure. * @newsk pointer to new sock structure.
* @sctp_assoc_established:
* Passes the @asoc and @chunk->skb of the association COOKIE_ACK packet
* to the security module.
* @asoc pointer to sctp association structure.
* @skb pointer to skbuff of association packet.
* *
* Security hooks for Infiniband * Security hooks for Infiniband
* *
......
...@@ -1422,6 +1422,8 @@ int security_sctp_bind_connect(struct sock *sk, int optname, ...@@ -1422,6 +1422,8 @@ int security_sctp_bind_connect(struct sock *sk, int optname,
struct sockaddr *address, int addrlen); struct sockaddr *address, int addrlen);
void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk, void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
struct sock *newsk); struct sock *newsk);
int security_sctp_assoc_established(struct sctp_association *asoc,
struct sk_buff *skb);
#else /* CONFIG_SECURITY_NETWORK */ #else /* CONFIG_SECURITY_NETWORK */
static inline int security_unix_stream_connect(struct sock *sock, static inline int security_unix_stream_connect(struct sock *sock,
...@@ -1641,6 +1643,12 @@ static inline void security_sctp_sk_clone(struct sctp_association *asoc, ...@@ -1641,6 +1643,12 @@ static inline void security_sctp_sk_clone(struct sctp_association *asoc,
struct sock *newsk) struct sock *newsk)
{ {
} }
static inline int security_sctp_assoc_established(struct sctp_association *asoc,
struct sk_buff *skb)
{
return 0;
}
#endif /* CONFIG_SECURITY_NETWORK */ #endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_INFINIBAND #ifdef CONFIG_SECURITY_INFINIBAND
......
...@@ -930,6 +930,11 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net, ...@@ -930,6 +930,11 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
if (!sctp_vtag_verify(chunk, asoc)) if (!sctp_vtag_verify(chunk, asoc))
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Set peer label for connection. */
if (security_sctp_assoc_established((struct sctp_association *)asoc,
chunk->skb))
return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands);
/* Verify that the chunk length for the COOKIE-ACK is OK. /* Verify that the chunk length for the COOKIE-ACK is OK.
* If we don't do this, any bundled chunks may be junked. * If we don't do this, any bundled chunks may be junked.
*/ */
...@@ -945,9 +950,6 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net, ...@@ -945,9 +950,6 @@ enum sctp_disposition sctp_sf_do_5_1E_ca(struct net *net,
*/ */
sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL());
/* Set peer label for connection. */
security_inet_conn_established(ep->base.sk, chunk->skb);
/* RFC 2960 5.1 Normal Establishment of an Association /* RFC 2960 5.1 Normal Establishment of an Association
* *
* E) Upon reception of the COOKIE ACK, endpoint "A" will move * E) Upon reception of the COOKIE ACK, endpoint "A" will move
......
...@@ -884,9 +884,22 @@ int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) ...@@ -884,9 +884,22 @@ int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc)
return call_int_hook(fs_context_dup, 0, fc, src_fc); return call_int_hook(fs_context_dup, 0, fc, src_fc);
} }
int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param) int security_fs_context_parse_param(struct fs_context *fc,
struct fs_parameter *param)
{ {
return call_int_hook(fs_context_parse_param, -ENOPARAM, fc, param); struct security_hook_list *hp;
int trc;
int rc = -ENOPARAM;
hlist_for_each_entry(hp, &security_hook_heads.fs_context_parse_param,
list) {
trc = hp->hook.fs_context_parse_param(fc, param);
if (trc == 0)
rc = 0;
else if (trc != -ENOPARAM)
return trc;
}
return rc;
} }
int security_sb_alloc(struct super_block *sb) int security_sb_alloc(struct super_block *sb)
...@@ -2391,6 +2404,13 @@ void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk, ...@@ -2391,6 +2404,13 @@ void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk,
} }
EXPORT_SYMBOL(security_sctp_sk_clone); EXPORT_SYMBOL(security_sctp_sk_clone);
int security_sctp_assoc_established(struct sctp_association *asoc,
struct sk_buff *skb)
{
return call_int_hook(sctp_assoc_established, 0, asoc, skb);
}
EXPORT_SYMBOL(security_sctp_assoc_established);
#endif /* CONFIG_SECURITY_NETWORK */ #endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_INFINIBAND #ifdef CONFIG_SECURITY_INFINIBAND
......
...@@ -211,10 +211,9 @@ static int selinux_lsm_notifier_avc_callback(u32 event) ...@@ -211,10 +211,9 @@ static int selinux_lsm_notifier_avc_callback(u32 event)
*/ */
static void cred_init_security(void) static void cred_init_security(void)
{ {
struct cred *cred = (struct cred *) current->real_cred;
struct task_security_struct *tsec; struct task_security_struct *tsec;
tsec = selinux_cred(cred); tsec = selinux_cred(unrcu_pointer(current->real_cred));
tsec->osid = tsec->sid = SECINITSID_KERNEL; tsec->osid = tsec->sid = SECINITSID_KERNEL;
} }
...@@ -341,17 +340,15 @@ static void inode_free_security(struct inode *inode) ...@@ -341,17 +340,15 @@ static void inode_free_security(struct inode *inode)
} }
struct selinux_mnt_opts { struct selinux_mnt_opts {
const char *fscontext, *context, *rootcontext, *defcontext; u32 fscontext_sid;
u32 context_sid;
u32 rootcontext_sid;
u32 defcontext_sid;
}; };
static void selinux_free_mnt_opts(void *mnt_opts) static void selinux_free_mnt_opts(void *mnt_opts)
{ {
struct selinux_mnt_opts *opts = mnt_opts; kfree(mnt_opts);
kfree(opts->fscontext);
kfree(opts->context);
kfree(opts->rootcontext);
kfree(opts->defcontext);
kfree(opts);
} }
enum { enum {
...@@ -479,7 +476,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) ...@@ -479,7 +476,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb)
static int sb_check_xattr_support(struct super_block *sb) static int sb_check_xattr_support(struct super_block *sb)
{ {
struct superblock_security_struct *sbsec = sb->s_security; struct superblock_security_struct *sbsec = selinux_superblock(sb);
struct dentry *root = sb->s_root; struct dentry *root = sb->s_root;
struct inode *root_inode = d_backing_inode(root); struct inode *root_inode = d_backing_inode(root);
u32 sid; u32 sid;
...@@ -598,18 +595,6 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag, ...@@ -598,18 +595,6 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
return 0; return 0;
} }
static int parse_sid(struct super_block *sb, const char *s, u32 *sid,
gfp_t gfp)
{
int rc = security_context_str_to_sid(&selinux_state, s,
sid, gfp);
if (rc)
pr_warn("SELinux: security_context_str_to_sid"
"(%s) failed for (dev %s, type %s) errno=%d\n",
s, sb->s_id, sb->s_type->name, rc);
return rc;
}
/* /*
* Allow filesystems with binary mount data to explicitly set mount point * Allow filesystems with binary mount data to explicitly set mount point
* labeling information. * labeling information.
...@@ -672,41 +657,29 @@ static int selinux_set_mnt_opts(struct super_block *sb, ...@@ -672,41 +657,29 @@ static int selinux_set_mnt_opts(struct super_block *sb,
* than once with different security options. * than once with different security options.
*/ */
if (opts) { if (opts) {
if (opts->fscontext) { if (opts->fscontext_sid) {
rc = parse_sid(sb, opts->fscontext, &fscontext_sid, fscontext_sid = opts->fscontext_sid;
GFP_KERNEL);
if (rc)
goto out;
if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
fscontext_sid)) fscontext_sid))
goto out_double_mount; goto out_double_mount;
sbsec->flags |= FSCONTEXT_MNT; sbsec->flags |= FSCONTEXT_MNT;
} }
if (opts->context) { if (opts->context_sid) {
rc = parse_sid(sb, opts->context, &context_sid, context_sid = opts->context_sid;
GFP_KERNEL);
if (rc)
goto out;
if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
context_sid)) context_sid))
goto out_double_mount; goto out_double_mount;
sbsec->flags |= CONTEXT_MNT; sbsec->flags |= CONTEXT_MNT;
} }
if (opts->rootcontext) { if (opts->rootcontext_sid) {
rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid, rootcontext_sid = opts->rootcontext_sid;
GFP_KERNEL);
if (rc)
goto out;
if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
rootcontext_sid)) rootcontext_sid))
goto out_double_mount; goto out_double_mount;
sbsec->flags |= ROOTCONTEXT_MNT; sbsec->flags |= ROOTCONTEXT_MNT;
} }
if (opts->defcontext) { if (opts->defcontext_sid) {
rc = parse_sid(sb, opts->defcontext, &defcontext_sid, defcontext_sid = opts->defcontext_sid;
GFP_KERNEL);
if (rc)
goto out;
if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
defcontext_sid)) defcontext_sid))
goto out_double_mount; goto out_double_mount;
...@@ -976,6 +949,8 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts) ...@@ -976,6 +949,8 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
{ {
struct selinux_mnt_opts *opts = *mnt_opts; struct selinux_mnt_opts *opts = *mnt_opts;
bool is_alloc_opts = false; bool is_alloc_opts = false;
u32 *dst_sid;
int rc;
if (token == Opt_seclabel) if (token == Opt_seclabel)
/* eaten and completely ignored */ /* eaten and completely ignored */
...@@ -983,6 +958,11 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts) ...@@ -983,6 +958,11 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
if (!s) if (!s)
return -ENOMEM; return -ENOMEM;
if (!selinux_initialized(&selinux_state)) {
pr_warn("SELinux: Unable to set superblock options before the security server is initialized\n");
return -EINVAL;
}
if (!opts) { if (!opts) {
opts = kzalloc(sizeof(*opts), GFP_KERNEL); opts = kzalloc(sizeof(*opts), GFP_KERNEL);
if (!opts) if (!opts)
...@@ -993,28 +973,34 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts) ...@@ -993,28 +973,34 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
switch (token) { switch (token) {
case Opt_context: case Opt_context:
if (opts->context || opts->defcontext) if (opts->context_sid || opts->defcontext_sid)
goto err; goto err;
opts->context = s; dst_sid = &opts->context_sid;
break; break;
case Opt_fscontext: case Opt_fscontext:
if (opts->fscontext) if (opts->fscontext_sid)
goto err; goto err;
opts->fscontext = s; dst_sid = &opts->fscontext_sid;
break; break;
case Opt_rootcontext: case Opt_rootcontext:
if (opts->rootcontext) if (opts->rootcontext_sid)
goto err; goto err;
opts->rootcontext = s; dst_sid = &opts->rootcontext_sid;
break; break;
case Opt_defcontext: case Opt_defcontext:
if (opts->context || opts->defcontext) if (opts->context_sid || opts->defcontext_sid)
goto err; goto err;
opts->defcontext = s; dst_sid = &opts->defcontext_sid;
break; break;
default:
WARN_ON(1);
return -EINVAL;
} }
rc = security_context_str_to_sid(&selinux_state, s, dst_sid, GFP_KERNEL);
return 0; if (rc)
pr_warn("SELinux: security_context_str_to_sid (%s) failed with errno=%d\n",
s, rc);
return rc;
err: err:
if (is_alloc_opts) { if (is_alloc_opts) {
...@@ -2535,7 +2521,7 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) ...@@ -2535,7 +2521,7 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
if (rc) { if (rc) {
clear_itimer(); clear_itimer();
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&unrcu_pointer(current->sighand)->siglock);
if (!fatal_signal_pending(current)) { if (!fatal_signal_pending(current)) {
flush_sigqueue(&current->pending); flush_sigqueue(&current->pending);
flush_sigqueue(&current->signal->shared_pending); flush_sigqueue(&current->signal->shared_pending);
...@@ -2543,13 +2529,13 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) ...@@ -2543,13 +2529,13 @@ static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
sigemptyset(&current->blocked); sigemptyset(&current->blocked);
recalc_sigpending(); recalc_sigpending();
} }
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&unrcu_pointer(current->sighand)->siglock);
} }
/* Wake up the parent if it is waiting so that it can recheck /* Wake up the parent if it is waiting so that it can recheck
* wait permission to the new task SID. */ * wait permission to the new task SID. */
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
__wake_up_parent(current, current->real_parent); __wake_up_parent(current, unrcu_pointer(current->real_parent));
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
} }
...@@ -2647,9 +2633,7 @@ static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts) ...@@ -2647,9 +2633,7 @@ static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts)
static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts) static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
{ {
struct selinux_mnt_opts *opts = mnt_opts; struct selinux_mnt_opts *opts = mnt_opts;
struct superblock_security_struct *sbsec = sb->s_security; struct superblock_security_struct *sbsec = selinux_superblock(sb);
u32 sid;
int rc;
/* /*
* Superblock not initialized (i.e. no options) - reject if any * Superblock not initialized (i.e. no options) - reject if any
...@@ -2665,35 +2649,27 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts) ...@@ -2665,35 +2649,27 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
if (!opts) if (!opts)
return (sbsec->flags & SE_MNTMASK) ? 1 : 0; return (sbsec->flags & SE_MNTMASK) ? 1 : 0;
if (opts->fscontext) { if (opts->fscontext_sid) {
rc = parse_sid(sb, opts->fscontext, &sid, GFP_NOWAIT); if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
if (rc) opts->fscontext_sid))
return 1;
if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
return 1; return 1;
} }
if (opts->context) { if (opts->context_sid) {
rc = parse_sid(sb, opts->context, &sid, GFP_NOWAIT); if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
if (rc) opts->context_sid))
return 1;
if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
return 1; return 1;
} }
if (opts->rootcontext) { if (opts->rootcontext_sid) {
struct inode_security_struct *root_isec; struct inode_security_struct *root_isec;
root_isec = backing_inode_security(sb->s_root); root_isec = backing_inode_security(sb->s_root);
rc = parse_sid(sb, opts->rootcontext, &sid, GFP_NOWAIT); if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
if (rc) opts->rootcontext_sid))
return 1;
if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
return 1; return 1;
} }
if (opts->defcontext) { if (opts->defcontext_sid) {
rc = parse_sid(sb, opts->defcontext, &sid, GFP_NOWAIT); if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
if (rc) opts->defcontext_sid))
return 1;
if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
return 1; return 1;
} }
return 0; return 0;
...@@ -2703,8 +2679,6 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) ...@@ -2703,8 +2679,6 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
{ {
struct selinux_mnt_opts *opts = mnt_opts; struct selinux_mnt_opts *opts = mnt_opts;
struct superblock_security_struct *sbsec = selinux_superblock(sb); struct superblock_security_struct *sbsec = selinux_superblock(sb);
u32 sid;
int rc;
if (!(sbsec->flags & SE_SBINITIALIZED)) if (!(sbsec->flags & SE_SBINITIALIZED))
return 0; return 0;
...@@ -2712,34 +2686,26 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts) ...@@ -2712,34 +2686,26 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
if (!opts) if (!opts)
return 0; return 0;
if (opts->fscontext) { if (opts->fscontext_sid) {
rc = parse_sid(sb, opts->fscontext, &sid, GFP_KERNEL); if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid,
if (rc) opts->fscontext_sid))
return rc;
if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
goto out_bad_option; goto out_bad_option;
} }
if (opts->context) { if (opts->context_sid) {
rc = parse_sid(sb, opts->context, &sid, GFP_KERNEL); if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid,
if (rc) opts->context_sid))
return rc;
if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
goto out_bad_option; goto out_bad_option;
} }
if (opts->rootcontext) { if (opts->rootcontext_sid) {
struct inode_security_struct *root_isec; struct inode_security_struct *root_isec;
root_isec = backing_inode_security(sb->s_root); root_isec = backing_inode_security(sb->s_root);
rc = parse_sid(sb, opts->rootcontext, &sid, GFP_KERNEL); if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid,
if (rc) opts->rootcontext_sid))
return rc;
if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
goto out_bad_option; goto out_bad_option;
} }
if (opts->defcontext) { if (opts->defcontext_sid) {
rc = parse_sid(sb, opts->defcontext, &sid, GFP_KERNEL); if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid,
if (rc) opts->defcontext_sid))
return rc;
if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
goto out_bad_option; goto out_bad_option;
} }
return 0; return 0;
...@@ -2806,38 +2772,12 @@ static int selinux_fs_context_dup(struct fs_context *fc, ...@@ -2806,38 +2772,12 @@ static int selinux_fs_context_dup(struct fs_context *fc,
struct fs_context *src_fc) struct fs_context *src_fc)
{ {
const struct selinux_mnt_opts *src = src_fc->security; const struct selinux_mnt_opts *src = src_fc->security;
struct selinux_mnt_opts *opts;
if (!src) if (!src)
return 0; return 0;
fc->security = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); fc->security = kmemdup(src, sizeof(*src), GFP_KERNEL);
if (!fc->security) return fc->security ? 0 : -ENOMEM;
return -ENOMEM;
opts = fc->security;
if (src->fscontext) {
opts->fscontext = kstrdup(src->fscontext, GFP_KERNEL);
if (!opts->fscontext)
return -ENOMEM;
}
if (src->context) {
opts->context = kstrdup(src->context, GFP_KERNEL);
if (!opts->context)
return -ENOMEM;
}
if (src->rootcontext) {
opts->rootcontext = kstrdup(src->rootcontext, GFP_KERNEL);
if (!opts->rootcontext)
return -ENOMEM;
}
if (src->defcontext) {
opts->defcontext = kstrdup(src->defcontext, GFP_KERNEL);
if (!opts->defcontext)
return -ENOMEM;
}
return 0;
} }
static const struct fs_parameter_spec selinux_fs_parameters[] = { static const struct fs_parameter_spec selinux_fs_parameters[] = {
...@@ -2860,10 +2800,9 @@ static int selinux_fs_context_parse_param(struct fs_context *fc, ...@@ -2860,10 +2800,9 @@ static int selinux_fs_context_parse_param(struct fs_context *fc,
return opt; return opt;
rc = selinux_add_opt(opt, param->string, &fc->security); rc = selinux_add_opt(opt, param->string, &fc->security);
if (!rc) { if (!rc)
param->string = NULL; param->string = NULL;
rc = 1;
}
return rc; return rc;
} }
...@@ -3345,8 +3284,6 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, ...@@ -3345,8 +3284,6 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
isec->sid = newsid; isec->sid = newsid;
isec->initialized = LABEL_INITIALIZED; isec->initialized = LABEL_INITIALIZED;
spin_unlock(&isec->lock); spin_unlock(&isec->lock);
return;
} }
static int selinux_inode_getxattr(struct dentry *dentry, const char *name) static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
...@@ -3745,6 +3682,12 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, ...@@ -3745,6 +3682,12 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
CAP_OPT_NONE, true); CAP_OPT_NONE, true);
break; break;
case FIOCLEX:
case FIONCLEX:
if (!selinux_policycap_ioctl_skip_cloexec())
error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd);
break;
/* default case assumes that the command will go /* default case assumes that the command will go
* to the file's ioctl() function. * to the file's ioctl() function.
*/ */
...@@ -5299,37 +5242,38 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) ...@@ -5299,37 +5242,38 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent)
sksec->sclass = isec->sclass; sksec->sclass = isec->sclass;
} }
/* Called whenever SCTP receives an INIT chunk. This happens when an incoming /*
* connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association * Determines peer_secid for the asoc and updates socket's peer label
* already present). * if it's the first association on the socket.
*/ */
static int selinux_sctp_assoc_request(struct sctp_association *asoc, static int selinux_sctp_process_new_assoc(struct sctp_association *asoc,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct sk_security_struct *sksec = asoc->base.sk->sk_security; struct sock *sk = asoc->base.sk;
u16 family = sk->sk_family;
struct sk_security_struct *sksec = sk->sk_security;
struct common_audit_data ad; struct common_audit_data ad;
struct lsm_network_audit net = {0,}; struct lsm_network_audit net = {0,};
u8 peerlbl_active; int err;
u32 peer_sid = SECINITSID_UNLABELED;
u32 conn_sid;
int err = 0;
if (!selinux_policycap_extsockclass()) /* handle mapped IPv4 packets arriving via IPv6 sockets */
return 0; if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
family = PF_INET;
peerlbl_active = selinux_peerlbl_enabled(); if (selinux_peerlbl_enabled()) {
asoc->peer_secid = SECSID_NULL;
if (peerlbl_active) {
/* This will return peer_sid = SECSID_NULL if there are /* This will return peer_sid = SECSID_NULL if there are
* no peer labels, see security_net_peersid_resolve(). * no peer labels, see security_net_peersid_resolve().
*/ */
err = selinux_skb_peerlbl_sid(skb, asoc->base.sk->sk_family, err = selinux_skb_peerlbl_sid(skb, family, &asoc->peer_secid);
&peer_sid);
if (err) if (err)
return err; return err;
if (peer_sid == SECSID_NULL) if (asoc->peer_secid == SECSID_NULL)
peer_sid = SECINITSID_UNLABELED; asoc->peer_secid = SECINITSID_UNLABELED;
} else {
asoc->peer_secid = SECINITSID_UNLABELED;
} }
if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) { if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) {
...@@ -5340,8 +5284,8 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc, ...@@ -5340,8 +5284,8 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc,
* then it is approved by policy and used as the primary * then it is approved by policy and used as the primary
* peer SID for getpeercon(3). * peer SID for getpeercon(3).
*/ */
sksec->peer_sid = peer_sid; sksec->peer_sid = asoc->peer_secid;
} else if (sksec->peer_sid != peer_sid) { } else if (sksec->peer_sid != asoc->peer_secid) {
/* Other association peer SIDs are checked to enforce /* Other association peer SIDs are checked to enforce
* consistency among the peer SIDs. * consistency among the peer SIDs.
*/ */
...@@ -5349,11 +5293,32 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc, ...@@ -5349,11 +5293,32 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc,
ad.u.net = &net; ad.u.net = &net;
ad.u.net->sk = asoc->base.sk; ad.u.net->sk = asoc->base.sk;
err = avc_has_perm(&selinux_state, err = avc_has_perm(&selinux_state,
sksec->peer_sid, peer_sid, sksec->sclass, sksec->peer_sid, asoc->peer_secid,
SCTP_SOCKET__ASSOCIATION, &ad); sksec->sclass, SCTP_SOCKET__ASSOCIATION,
&ad);
if (err) if (err)
return err; return err;
} }
return 0;
}
/* Called whenever SCTP receives an INIT or COOKIE ECHO chunk. This
* happens on an incoming connect(2), sctp_connectx(3) or
* sctp_sendmsg(3) (with no association already present).
*/
static int selinux_sctp_assoc_request(struct sctp_association *asoc,
struct sk_buff *skb)
{
struct sk_security_struct *sksec = asoc->base.sk->sk_security;
u32 conn_sid;
int err;
if (!selinux_policycap_extsockclass())
return 0;
err = selinux_sctp_process_new_assoc(asoc, skb);
if (err)
return err;
/* Compute the MLS component for the connection and store /* Compute the MLS component for the connection and store
* the information in asoc. This will be used by SCTP TCP type * the information in asoc. This will be used by SCTP TCP type
...@@ -5361,17 +5326,36 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc, ...@@ -5361,17 +5326,36 @@ static int selinux_sctp_assoc_request(struct sctp_association *asoc,
* socket to be generated. selinux_sctp_sk_clone() will then * socket to be generated. selinux_sctp_sk_clone() will then
* plug this into the new socket. * plug this into the new socket.
*/ */
err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid); err = selinux_conn_sid(sksec->sid, asoc->peer_secid, &conn_sid);
if (err) if (err)
return err; return err;
asoc->secid = conn_sid; asoc->secid = conn_sid;
asoc->peer_secid = peer_sid;
/* Set any NetLabel labels including CIPSO/CALIPSO options. */ /* Set any NetLabel labels including CIPSO/CALIPSO options. */
return selinux_netlbl_sctp_assoc_request(asoc, skb); return selinux_netlbl_sctp_assoc_request(asoc, skb);
} }
/* Called when SCTP receives a COOKIE ACK chunk as the final
* response to an association request (initited by us).
*/
static int selinux_sctp_assoc_established(struct sctp_association *asoc,
struct sk_buff *skb)
{
struct sk_security_struct *sksec = asoc->base.sk->sk_security;
if (!selinux_policycap_extsockclass())
return 0;
/* Inherit secid from the parent socket - this will be picked up
* by selinux_sctp_sk_clone() if the association gets peeled off
* into a new socket.
*/
asoc->secid = sksec->sid;
return selinux_sctp_process_new_assoc(asoc, skb);
}
/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting /* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting
* based on their @optname. * based on their @optname.
*/ */
...@@ -7192,6 +7176,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { ...@@ -7192,6 +7176,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request), LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request),
LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone), LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone),
LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect), LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect),
LSM_HOOK_INIT(sctp_assoc_established, selinux_sctp_assoc_established),
LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request), LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request),
LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone), LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone),
LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established), LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
......
...@@ -104,7 +104,7 @@ static void sel_ib_pkey_insert(struct sel_ib_pkey *pkey) ...@@ -104,7 +104,7 @@ static void sel_ib_pkey_insert(struct sel_ib_pkey *pkey)
tail = list_entry( tail = list_entry(
rcu_dereference_protected( rcu_dereference_protected(
sel_ib_pkey_hash[idx].list.prev, list_tail_rcu(&sel_ib_pkey_hash[idx].list),
lockdep_is_held(&sel_ib_pkey_lock)), lockdep_is_held(&sel_ib_pkey_lock)),
struct sel_ib_pkey, list); struct sel_ib_pkey, list);
list_del_rcu(&tail->list); list_del_rcu(&tail->list);
......
...@@ -29,7 +29,7 @@ static char *selinux_ima_collect_state(struct selinux_state *state) ...@@ -29,7 +29,7 @@ static char *selinux_ima_collect_state(struct selinux_state *state)
buf_len = strlen("initialized=0;enforcing=0;checkreqprot=0;") + 1; buf_len = strlen("initialized=0;enforcing=0;checkreqprot=0;") + 1;
len = strlen(on); len = strlen(on);
for (i = 0; i < __POLICYDB_CAPABILITY_MAX; i++) for (i = 0; i < __POLICYDB_CAP_MAX; i++)
buf_len += strlen(selinux_policycap_names[i]) + len; buf_len += strlen(selinux_policycap_names[i]) + len;
buf = kzalloc(buf_len, GFP_KERNEL); buf = kzalloc(buf_len, GFP_KERNEL);
...@@ -54,7 +54,7 @@ static char *selinux_ima_collect_state(struct selinux_state *state) ...@@ -54,7 +54,7 @@ static char *selinux_ima_collect_state(struct selinux_state *state)
rc = strlcat(buf, checkreqprot_get(state) ? on : off, buf_len); rc = strlcat(buf, checkreqprot_get(state) ? on : off, buf_len);
WARN_ON(rc >= buf_len); WARN_ON(rc >= buf_len);
for (i = 0; i < __POLICYDB_CAPABILITY_MAX; i++) { for (i = 0; i < __POLICYDB_CAP_MAX; i++) {
rc = strlcat(buf, selinux_policycap_names[i], buf_len); rc = strlcat(buf, selinux_policycap_names[i], buf_len);
WARN_ON(rc >= buf_len); WARN_ON(rc >= buf_len);
......
...@@ -4,17 +4,18 @@ ...@@ -4,17 +4,18 @@
/* Policy capabilities */ /* Policy capabilities */
enum { enum {
POLICYDB_CAPABILITY_NETPEER, POLICYDB_CAP_NETPEER,
POLICYDB_CAPABILITY_OPENPERM, POLICYDB_CAP_OPENPERM,
POLICYDB_CAPABILITY_EXTSOCKCLASS, POLICYDB_CAP_EXTSOCKCLASS,
POLICYDB_CAPABILITY_ALWAYSNETWORK, POLICYDB_CAP_ALWAYSNETWORK,
POLICYDB_CAPABILITY_CGROUPSECLABEL, POLICYDB_CAP_CGROUPSECLABEL,
POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION, POLICYDB_CAP_NNP_NOSUID_TRANSITION,
POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS, POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS,
__POLICYDB_CAPABILITY_MAX POLICYDB_CAP_IOCTL_SKIP_CLOEXEC,
__POLICYDB_CAP_MAX
}; };
#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1)
extern const char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX]; extern const char *selinux_policycap_names[__POLICYDB_CAP_MAX];
#endif /* _SELINUX_POLICYCAP_H_ */ #endif /* _SELINUX_POLICYCAP_H_ */
...@@ -5,14 +5,15 @@ ...@@ -5,14 +5,15 @@
#include "policycap.h" #include "policycap.h"
/* Policy capability names */ /* Policy capability names */
const char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = { const char *selinux_policycap_names[__POLICYDB_CAP_MAX] = {
"network_peer_controls", "network_peer_controls",
"open_perms", "open_perms",
"extended_socket_class", "extended_socket_class",
"always_check_network", "always_check_network",
"cgroup_seclabel", "cgroup_seclabel",
"nnp_nosuid_transition", "nnp_nosuid_transition",
"genfs_seclabel_symlinks" "genfs_seclabel_symlinks",
"ioctl_skip_cloexec"
}; };
#endif /* _SELINUX_POLICYCAP_NAMES_H_ */ #endif /* _SELINUX_POLICYCAP_NAMES_H_ */
...@@ -96,7 +96,7 @@ struct selinux_state { ...@@ -96,7 +96,7 @@ struct selinux_state {
#endif #endif
bool checkreqprot; bool checkreqprot;
bool initialized; bool initialized;
bool policycap[__POLICYDB_CAPABILITY_MAX]; bool policycap[__POLICYDB_CAP_MAX];
struct page *status_page; struct page *status_page;
struct mutex status_lock; struct mutex status_lock;
...@@ -174,49 +174,56 @@ static inline bool selinux_policycap_netpeer(void) ...@@ -174,49 +174,56 @@ static inline bool selinux_policycap_netpeer(void)
{ {
struct selinux_state *state = &selinux_state; struct selinux_state *state = &selinux_state;
return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_NETPEER]); return READ_ONCE(state->policycap[POLICYDB_CAP_NETPEER]);
} }
static inline bool selinux_policycap_openperm(void) static inline bool selinux_policycap_openperm(void)
{ {
struct selinux_state *state = &selinux_state; struct selinux_state *state = &selinux_state;
return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_OPENPERM]); return READ_ONCE(state->policycap[POLICYDB_CAP_OPENPERM]);
} }
static inline bool selinux_policycap_extsockclass(void) static inline bool selinux_policycap_extsockclass(void)
{ {
struct selinux_state *state = &selinux_state; struct selinux_state *state = &selinux_state;
return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS]); return READ_ONCE(state->policycap[POLICYDB_CAP_EXTSOCKCLASS]);
} }
static inline bool selinux_policycap_alwaysnetwork(void) static inline bool selinux_policycap_alwaysnetwork(void)
{ {
struct selinux_state *state = &selinux_state; struct selinux_state *state = &selinux_state;
return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK]); return READ_ONCE(state->policycap[POLICYDB_CAP_ALWAYSNETWORK]);
} }
static inline bool selinux_policycap_cgroupseclabel(void) static inline bool selinux_policycap_cgroupseclabel(void)
{ {
struct selinux_state *state = &selinux_state; struct selinux_state *state = &selinux_state;
return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL]); return READ_ONCE(state->policycap[POLICYDB_CAP_CGROUPSECLABEL]);
} }
static inline bool selinux_policycap_nnp_nosuid_transition(void) static inline bool selinux_policycap_nnp_nosuid_transition(void)
{ {
struct selinux_state *state = &selinux_state; struct selinux_state *state = &selinux_state;
return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION]); return READ_ONCE(state->policycap[POLICYDB_CAP_NNP_NOSUID_TRANSITION]);
} }
static inline bool selinux_policycap_genfs_seclabel_symlinks(void) static inline bool selinux_policycap_genfs_seclabel_symlinks(void)
{ {
struct selinux_state *state = &selinux_state; struct selinux_state *state = &selinux_state;
return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS]); return READ_ONCE(state->policycap[POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS]);
}
static inline bool selinux_policycap_ioctl_skip_cloexec(void)
{
struct selinux_state *state = &selinux_state;
return READ_ONCE(state->policycap[POLICYDB_CAP_IOCTL_SKIP_CLOEXEC]);
} }
struct selinux_policy_convert_data; struct selinux_policy_convert_data;
...@@ -254,8 +261,8 @@ struct av_decision { ...@@ -254,8 +261,8 @@ struct av_decision {
#define XPERMS_AUDITALLOW 2 #define XPERMS_AUDITALLOW 2
#define XPERMS_DONTAUDIT 4 #define XPERMS_DONTAUDIT 4
#define security_xperm_set(perms, x) (perms[x >> 5] |= 1 << (x & 0x1f)) #define security_xperm_set(perms, x) ((perms)[(x) >> 5] |= 1 << ((x) & 0x1f))
#define security_xperm_test(perms, x) (1 & (perms[x >> 5] >> (x & 0x1f))) #define security_xperm_test(perms, x) (1 & ((perms)[(x) >> 5] >> ((x) & 0x1f)))
struct extended_perms_data { struct extended_perms_data {
u32 p[8]; u32 p[8];
}; };
...@@ -386,11 +393,11 @@ int security_get_allow_unknown(struct selinux_state *state); ...@@ -386,11 +393,11 @@ int security_get_allow_unknown(struct selinux_state *state);
int security_fs_use(struct selinux_state *state, struct super_block *sb); int security_fs_use(struct selinux_state *state, struct super_block *sb);
int security_genfs_sid(struct selinux_state *state, int security_genfs_sid(struct selinux_state *state,
const char *fstype, char *name, u16 sclass, const char *fstype, const char *path, u16 sclass,
u32 *sid); u32 *sid);
int selinux_policy_genfs_sid(struct selinux_policy *policy, int selinux_policy_genfs_sid(struct selinux_policy *policy,
const char *fstype, char *name, u16 sclass, const char *fstype, const char *path, u16 sclass,
u32 *sid); u32 *sid);
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL
......
...@@ -107,7 +107,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) ...@@ -107,7 +107,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
switch (family) { switch (family) {
case PF_INET: case PF_INET:
idx = sel_netnode_hashfn_ipv4(*(__be32 *)addr); idx = sel_netnode_hashfn_ipv4(*(const __be32 *)addr);
break; break;
case PF_INET6: case PF_INET6:
idx = sel_netnode_hashfn_ipv6(addr); idx = sel_netnode_hashfn_ipv6(addr);
...@@ -121,7 +121,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) ...@@ -121,7 +121,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
if (node->nsec.family == family) if (node->nsec.family == family)
switch (family) { switch (family) {
case PF_INET: case PF_INET:
if (node->nsec.addr.ipv4 == *(__be32 *)addr) if (node->nsec.addr.ipv4 == *(const __be32 *)addr)
return node; return node;
break; break;
case PF_INET6: case PF_INET6:
...@@ -164,8 +164,9 @@ static void sel_netnode_insert(struct sel_netnode *node) ...@@ -164,8 +164,9 @@ static void sel_netnode_insert(struct sel_netnode *node)
if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) {
struct sel_netnode *tail; struct sel_netnode *tail;
tail = list_entry( tail = list_entry(
rcu_dereference_protected(sel_netnode_hash[idx].list.prev, rcu_dereference_protected(
lockdep_is_held(&sel_netnode_lock)), list_tail_rcu(&sel_netnode_hash[idx].list),
lockdep_is_held(&sel_netnode_lock)),
struct sel_netnode, list); struct sel_netnode, list);
list_del_rcu(&tail->list); list_del_rcu(&tail->list);
kfree_rcu(tail, rcu); kfree_rcu(tail, rcu);
......
...@@ -113,7 +113,7 @@ static void sel_netport_insert(struct sel_netport *port) ...@@ -113,7 +113,7 @@ static void sel_netport_insert(struct sel_netport *port)
struct sel_netport *tail; struct sel_netport *tail;
tail = list_entry( tail = list_entry(
rcu_dereference_protected( rcu_dereference_protected(
sel_netport_hash[idx].list.prev, list_tail_rcu(&sel_netport_hash[idx].list),
lockdep_is_held(&sel_netport_lock)), lockdep_is_held(&sel_netport_lock)),
struct sel_netport, list); struct sel_netport, list);
list_del_rcu(&tail->list); list_del_rcu(&tail->list);
......
...@@ -1983,7 +1983,7 @@ static int sel_make_policycap(struct selinux_fs_info *fsi) ...@@ -1983,7 +1983,7 @@ static int sel_make_policycap(struct selinux_fs_info *fsi)
struct dentry *dentry = NULL; struct dentry *dentry = NULL;
struct inode *inode = NULL; struct inode *inode = NULL;
for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) { for (iter = 0; iter <= POLICYDB_CAP_MAX; iter++) {
if (iter < ARRAY_SIZE(selinux_policycap_names)) if (iter < ARRAY_SIZE(selinux_policycap_names))
dentry = d_alloc_name(fsi->policycap_dir, dentry = d_alloc_name(fsi->policycap_dir,
selinux_policycap_names[iter]); selinux_policycap_names[iter]);
...@@ -2127,6 +2127,8 @@ static int sel_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -2127,6 +2127,8 @@ static int sel_fill_super(struct super_block *sb, struct fs_context *fc)
} }
ret = sel_make_avc_files(dentry); ret = sel_make_avc_files(dentry);
if (ret)
goto err;
dentry = sel_make_dir(sb->s_root, "ss", &fsi->last_ino); dentry = sel_make_dir(sb->s_root, "ss", &fsi->last_ino);
if (IS_ERR(dentry)) { if (IS_ERR(dentry)) {
......
...@@ -67,7 +67,7 @@ static inline int avtab_hash(const struct avtab_key *keyp, u32 mask) ...@@ -67,7 +67,7 @@ static inline int avtab_hash(const struct avtab_key *keyp, u32 mask)
static struct avtab_node* static struct avtab_node*
avtab_insert_node(struct avtab *h, int hvalue, avtab_insert_node(struct avtab *h, int hvalue,
struct avtab_node *prev, struct avtab_node *cur, struct avtab_node *prev,
const struct avtab_key *key, const struct avtab_datum *datum) const struct avtab_key *key, const struct avtab_datum *datum)
{ {
struct avtab_node *newnode; struct avtab_node *newnode;
...@@ -137,7 +137,7 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key, ...@@ -137,7 +137,7 @@ static int avtab_insert(struct avtab *h, const struct avtab_key *key,
break; break;
} }
newnode = avtab_insert_node(h, hvalue, prev, cur, key, datum); newnode = avtab_insert_node(h, hvalue, prev, key, datum);
if (!newnode) if (!newnode)
return -ENOMEM; return -ENOMEM;
...@@ -177,7 +177,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h, ...@@ -177,7 +177,7 @@ struct avtab_node *avtab_insert_nonunique(struct avtab *h,
key->target_class < cur->key.target_class) key->target_class < cur->key.target_class)
break; break;
} }
return avtab_insert_node(h, hvalue, prev, cur, key, datum); return avtab_insert_node(h, hvalue, prev, key, datum);
} }
struct avtab_datum *avtab_search(struct avtab *h, const struct avtab_key *key) struct avtab_datum *avtab_search(struct avtab *h, const struct avtab_key *key)
......
...@@ -567,8 +567,6 @@ void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key, ...@@ -567,8 +567,6 @@ void cond_compute_xperms(struct avtab *ctab, struct avtab_key *key,
if (node->key.specified & AVTAB_ENABLED) if (node->key.specified & AVTAB_ENABLED)
services_compute_xperms_decision(xpermd, node); services_compute_xperms_decision(xpermd, node);
} }
return;
} }
/* Determine whether additional permissions are granted by the conditional /* Determine whether additional permissions are granted by the conditional
* av table, and if so, add them to the result * av table, and if so, add them to the result
......
...@@ -359,7 +359,6 @@ void ebitmap_destroy(struct ebitmap *e) ...@@ -359,7 +359,6 @@ void ebitmap_destroy(struct ebitmap *e)
e->highbit = 0; e->highbit = 0;
e->node = NULL; e->node = NULL;
return;
} }
int ebitmap_read(struct ebitmap *e, void *fp) int ebitmap_read(struct ebitmap *e, void *fp)
......
...@@ -118,9 +118,9 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n, ...@@ -118,9 +118,9 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
} }
#define ebitmap_for_each_positive_bit(e, n, bit) \ #define ebitmap_for_each_positive_bit(e, n, bit) \
for (bit = ebitmap_start_positive(e, &n); \ for ((bit) = ebitmap_start_positive(e, &(n)); \
bit < ebitmap_length(e); \ (bit) < ebitmap_length(e); \
bit = ebitmap_next_positive(e, &n, bit)) \ (bit) = ebitmap_next_positive(e, &(n), bit)) \
int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2);
int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src); int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
......
...@@ -156,7 +156,6 @@ void mls_sid_to_context(struct policydb *p, ...@@ -156,7 +156,6 @@ void mls_sid_to_context(struct policydb *p,
} }
*scontext = scontextp; *scontext = scontextp;
return;
} }
int mls_level_isvalid(struct policydb *p, struct mls_level *l) int mls_level_isvalid(struct policydb *p, struct mls_level *l)
......
...@@ -41,8 +41,6 @@ ...@@ -41,8 +41,6 @@
#include "mls.h" #include "mls.h"
#include "services.h" #include "services.h"
#define _DEBUG_HASHES
#ifdef DEBUG_HASHES #ifdef DEBUG_HASHES
static const char *symtab_name[SYM_NUM] = { static const char *symtab_name[SYM_NUM] = {
"common prefixes", "common prefixes",
...@@ -704,7 +702,7 @@ static void symtab_hash_eval(struct symtab *s) ...@@ -704,7 +702,7 @@ static void symtab_hash_eval(struct symtab *s)
} }
#else #else
static inline void hash_eval(struct hashtab *h, char *hash_name) static inline void hash_eval(struct hashtab *h, const char *hash_name)
{ {
} }
#endif #endif
......
...@@ -529,8 +529,6 @@ static void security_dump_masked_av(struct policydb *policydb, ...@@ -529,8 +529,6 @@ static void security_dump_masked_av(struct policydb *policydb,
/* release scontext/tcontext */ /* release scontext/tcontext */
kfree(tcontext_name); kfree(tcontext_name);
kfree(scontext_name); kfree(scontext_name);
return;
} }
/* /*
...@@ -1452,7 +1450,7 @@ static int string_to_context_struct(struct policydb *pol, ...@@ -1452,7 +1450,7 @@ static int string_to_context_struct(struct policydb *pol,
/* Parse the security context. */ /* Parse the security context. */
rc = -EINVAL; rc = -EINVAL;
scontextp = (char *) scontext; scontextp = scontext;
/* Extract the user. */ /* Extract the user. */
p = scontextp; p = scontextp;
...@@ -2875,7 +2873,7 @@ int security_get_user_sids(struct selinux_state *state, ...@@ -2875,7 +2873,7 @@ int security_get_user_sids(struct selinux_state *state,
*/ */
static inline int __security_genfs_sid(struct selinux_policy *policy, static inline int __security_genfs_sid(struct selinux_policy *policy,
const char *fstype, const char *fstype,
char *path, const char *path,
u16 orig_sclass, u16 orig_sclass,
u32 *sid) u32 *sid)
{ {
...@@ -2928,7 +2926,7 @@ static inline int __security_genfs_sid(struct selinux_policy *policy, ...@@ -2928,7 +2926,7 @@ static inline int __security_genfs_sid(struct selinux_policy *policy,
*/ */
int security_genfs_sid(struct selinux_state *state, int security_genfs_sid(struct selinux_state *state,
const char *fstype, const char *fstype,
char *path, const char *path,
u16 orig_sclass, u16 orig_sclass,
u32 *sid) u32 *sid)
{ {
...@@ -2952,7 +2950,7 @@ int security_genfs_sid(struct selinux_state *state, ...@@ -2952,7 +2950,7 @@ int security_genfs_sid(struct selinux_state *state,
int selinux_policy_genfs_sid(struct selinux_policy *policy, int selinux_policy_genfs_sid(struct selinux_policy *policy,
const char *fstype, const char *fstype,
char *path, const char *path,
u16 orig_sclass, u16 orig_sclass,
u32 *sid) u32 *sid)
{ {
......
...@@ -27,8 +27,8 @@ struct sidtab_str_cache { ...@@ -27,8 +27,8 @@ struct sidtab_str_cache {
char str[]; char str[];
}; };
#define index_to_sid(index) (index + SECINITSID_NUM + 1) #define index_to_sid(index) ((index) + SECINITSID_NUM + 1)
#define sid_to_index(sid) (sid - (SECINITSID_NUM + 1)) #define sid_to_index(sid) ((sid) - (SECINITSID_NUM + 1))
int sidtab_init(struct sidtab *s) int sidtab_init(struct sidtab *s)
{ {
......
...@@ -347,7 +347,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, ...@@ -347,7 +347,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
int rc; int rc;
struct xfrm_sec_ctx *ctx; struct xfrm_sec_ctx *ctx;
char *ctx_str = NULL; char *ctx_str = NULL;
int str_len; u32 str_len;
if (!polsec) if (!polsec)
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment