@@ -867,7 +867,6 @@
* @sock is the socket
* @skb is the skbuff for the packet being queried
* @l is a pointer to a buffer in which to copy the security data
- * Return 0 on success, error on failure.
* @sk_alloc_security:
* Allocate and attach a security structure to the sk->sk_security field,
* which is used to copy security attributes between local stream sockets.
@@ -1681,7 +1680,7 @@ union security_list_options {
int (*socket_getpeersec_stream)(struct socket *sock,
char __user *optval,
int __user *optlen, unsigned len);
- int (*socket_getpeersec_dgram)(struct socket *sock,
+ void (*socket_getpeersec_dgram)(struct socket *sock,
struct sk_buff *skb,
struct lsm_export *l);
int (*sk_alloc_security)(struct sock *sk, int family, gfp_t priority);
@@ -1274,8 +1274,8 @@ int security_socket_shutdown(struct socket *sock, int how);
int security_sock_rcv_skb(struct sock *sk, struct sk_buff *skb);
int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
int __user *optlen, unsigned len);
-int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb,
- struct lsm_export *l);
+void security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb,
+ struct lsm_export *l);
int security_sk_alloc(struct sock *sk, int family, gfp_t priority);
void security_sk_free(struct sock *sk);
void security_sk_clone(const struct sock *sk, struct sock *newsk);
@@ -1413,11 +1413,10 @@ static inline int security_socket_getpeersec_stream(struct socket *sock, char __
return -ENOPROTOOPT;
}
-static inline int security_socket_getpeersec_dgram(struct socket *sock,
- struct sk_buff *skb,
- struct lsm_export *l)
+static inline void security_socket_getpeersec_dgram(struct socket *sock,
+ struct sk_buff *skb,
+ struct lsm_export *l)
{
- return -ENOPROTOOPT;
}
static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
@@ -134,9 +134,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
struct lsm_context lc;
int err;
- err = security_socket_getpeersec_dgram(NULL, skb, &le);
- if (err)
- return;
+ security_socket_getpeersec_dgram(NULL, skb, &le);
err = security_secid_to_secctx(&le, &lc);
if (err)
@@ -2414,12 +2414,11 @@ int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
optval, optlen, len);
}
-int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb,
- struct lsm_export *l)
+void security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb,
+ struct lsm_export *l)
{
lsm_export_init(l);
- return call_int_hook(socket_getpeersec_dgram, -ENOPROTOOPT, sock, skb,
- l);
+ call_void_hook(socket_getpeersec_dgram, sock, skb, l);
}
EXPORT_SYMBOL(security_socket_getpeersec_dgram);
@@ -4835,9 +4835,9 @@ static int selinux_socket_getpeersec_stream(struct socket *sock,
return err;
}
-static int selinux_socket_getpeersec_dgram(struct socket *sock,
- struct sk_buff *skb,
- struct lsm_export *l)
+static void selinux_socket_getpeersec_dgram(struct socket *sock,
+ struct sk_buff *skb,
+ struct lsm_export *l)
{
u32 peer_secid = SECSID_NULL;
u16 family;
@@ -4860,9 +4860,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock,
out:
selinux_export_secid(l, peer_secid);
- if (peer_secid == SECSID_NULL)
- return -EINVAL;
- return 0;
+ return;
}
static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
@@ -6206,6 +6204,9 @@ static int selinux_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
u32 secid;
selinux_import_secid(l, &secid);
+ if (secid == SECSID_NULL)
+ return -EINVAL;
+
cp->release = selinux_release_secctx;
if (l->flags & LSM_EXPORT_LENGTH)
return security_sid_to_context(&selinux_state, secid,
@@ -3902,9 +3902,9 @@ static int smack_socket_getpeersec_stream(struct socket *sock,
*
* Sets the netlabel socket state on sk from parent
*/
-static int smack_socket_getpeersec_dgram(struct socket *sock,
- struct sk_buff *skb,
- struct lsm_export *l)
+static void smack_socket_getpeersec_dgram(struct socket *sock,
+ struct sk_buff *skb,
+ struct lsm_export *l)
{
struct netlbl_lsm_secattr secattr;
@@ -3912,7 +3912,6 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
struct smack_known *skp;
int family = PF_UNSPEC;
u32 s = 0; /* 0 is the invalid secid */
- int rc;
if (skb != NULL) {
if (skb->protocol == htons(ETH_P_IP))
@@ -3942,8 +3941,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
if (sock != NULL && sock->sk != NULL)
ssp = smack_sock(sock->sk);
netlbl_secattr_init(&secattr);
- rc = netlbl_skbuff_getattr(skb, family, &secattr);
- if (rc == 0) {
+ if (netlbl_skbuff_getattr(skb, family, &secattr) == 0) {
skp = smack_from_secattr(&secattr, ssp);
s = skp->smk_secid;
}
@@ -3958,9 +3956,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock,
break;
}
smack_export_secid(l, s);
- if (s == 0)
- return -EINVAL;
- return 0;
+ return;
}
/**
@@ -4373,6 +4369,9 @@ static int smack_secid_to_secctx(struct lsm_export *l, struct lsm_context *cp)
u32 secid;
smack_import_secid(l, &secid);
+ if (secid == 0)
+ return -EINVAL;
+
skp = smack_from_secid(secid);
cp->context = (l->flags & LSM_EXPORT_LENGTH) ? NULL : skp->smk_known;
security_socket_getpeercred_dgram() supplies secids for use by security_secid_to_secctx(). Sometimes a secid will be invalid. Move the check for an invalid secid from the LSM specific socket_getpeercred_dgram hooks into the secid_to_secctx hooks. This allows for the case where one LSM (Smack) will provide a secid and another (SELinux) to have an error for the same call. Regardless of which LSM the caller wants to see the peer security attributes for the correct result will be provided. As there is no longer any reason for security_secid_to_secctx() to return a value make all the secid_to_secctx functions void instead of int. Add checking for a invalid secid to the Smack and SELinux secid_to_secctx hooks. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- include/linux/lsm_hooks.h | 3 +-- include/linux/security.h | 11 +++++------ net/ipv4/ip_sockglue.c | 4 +--- security/security.c | 7 +++---- security/selinux/hooks.c | 13 +++++++------ security/smack/smack_lsm.c | 17 ++++++++--------- 6 files changed, 25 insertions(+), 30 deletions(-)