Add cr_canseeinpcb() doing checks using the cached socket
credentials from inp_cred which is also available after the socket is gone. Switch cr_canseesocket consumers to cr_canseeinpcb. This removes an extra acquisition of the socket lock. Reviewed by: rwatson MFC after: 3 months (set timer; decide then)
This commit is contained in:
parent
dd8c8a8e43
commit
f08ef6c595
@ -45,6 +45,8 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_compat.h"
|
||||
#include "opt_inet.h"
|
||||
#include "opt_inet6.h"
|
||||
#include "opt_mac.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -68,6 +70,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/syscallsubr.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_pcb.h>
|
||||
#endif
|
||||
|
||||
#include <security/audit/audit.h>
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
@ -1704,6 +1711,34 @@ cr_canseesocket(struct ucred *cred, struct socket *so)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(INET) || defined(INET6)
|
||||
/*-
|
||||
* Determine whether the subject represented by cred can "see" a socket.
|
||||
* Returns: 0 for permitted, ENOENT otherwise.
|
||||
*/
|
||||
int
|
||||
cr_canseeinpcb(struct ucred *cred, struct inpcb *inp)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = prison_check(cred, inp->inp_cred);
|
||||
if (error)
|
||||
return (ENOENT);
|
||||
#ifdef MAC
|
||||
INP_LOCK_ASSERT(inp);
|
||||
error = mac_inpcb_check_visible(cred, inp);
|
||||
if (error)
|
||||
return (error);
|
||||
#endif
|
||||
if (cr_seeotheruids(cred, inp->inp_cred))
|
||||
return (ENOENT);
|
||||
if (cr_seeothergids(cred, inp->inp_cred))
|
||||
return (ENOENT);
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*-
|
||||
* Determine whether td can wait for the exit of p.
|
||||
* Returns: 0 for permitted, an errno value otherwise
|
||||
|
@ -627,7 +627,7 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
|
||||
inp = LIST_NEXT(inp, inp_list)) {
|
||||
INP_RLOCK(inp);
|
||||
if (inp->inp_gencnt <= gencnt &&
|
||||
cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0)
|
||||
cr_canseeinpcb(req->td->td_ucred, inp) == 0)
|
||||
inp_list[i++] = inp;
|
||||
INP_RUNLOCK(inp);
|
||||
}
|
||||
|
@ -942,7 +942,7 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
|
||||
inp = LIST_NEXT(inp, inp_list)) {
|
||||
INP_RLOCK(inp);
|
||||
if (inp->inp_gencnt <= gencnt &&
|
||||
cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0) {
|
||||
cr_canseeinpcb(req->td->td_ucred, inp) == 0) {
|
||||
/* XXX held references? */
|
||||
inp_list[i++] = inp;
|
||||
}
|
||||
|
@ -1015,8 +1015,7 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
|
||||
else
|
||||
error = EINVAL; /* Skip this inp. */
|
||||
} else
|
||||
error = cr_canseesocket(req->td->td_ucred,
|
||||
inp->inp_socket);
|
||||
error = cr_canseeinpcb(req->td->td_ucred, inp);
|
||||
if (error == 0)
|
||||
inp_list[i++] = inp;
|
||||
}
|
||||
@ -1104,8 +1103,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
|
||||
if (inp->inp_socket == NULL)
|
||||
error = ENOENT;
|
||||
if (error == 0)
|
||||
error = cr_canseesocket(req->td->td_ucred,
|
||||
inp->inp_socket);
|
||||
error = cr_canseeinpcb(req->td->td_ucred, inp);
|
||||
if (error == 0)
|
||||
cru2x(inp->inp_cred, &xuc);
|
||||
INP_RUNLOCK(inp);
|
||||
@ -1168,8 +1166,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
|
||||
if (inp->inp_socket == NULL)
|
||||
error = ENOENT;
|
||||
if (error == 0)
|
||||
error = cr_canseesocket(req->td->td_ucred,
|
||||
inp->inp_socket);
|
||||
error = cr_canseeinpcb(req->td->td_ucred, inp);
|
||||
if (error == 0)
|
||||
cru2x(inp->inp_cred, &xuc);
|
||||
INP_RUNLOCK(inp);
|
||||
|
@ -688,7 +688,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
|
||||
inp = LIST_NEXT(inp, inp_list)) {
|
||||
INP_RLOCK(inp);
|
||||
if (inp->inp_gencnt <= gencnt &&
|
||||
cr_canseesocket(req->td->td_ucred, inp->inp_socket) == 0)
|
||||
cr_canseeinpcb(req->td->td_ucred, inp) == 0)
|
||||
inp_list[i++] = inp;
|
||||
INP_RUNLOCK(inp);
|
||||
}
|
||||
@ -758,8 +758,7 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
|
||||
if (inp->inp_socket == NULL)
|
||||
error = ENOENT;
|
||||
if (error == 0)
|
||||
error = cr_canseesocket(req->td->td_ucred,
|
||||
inp->inp_socket);
|
||||
error = cr_canseeinpcb(req->td->td_ucred, inp);
|
||||
if (error == 0)
|
||||
cru2x(inp->inp_cred, &xuc);
|
||||
INP_RUNLOCK(inp);
|
||||
|
@ -112,6 +112,7 @@ extern char **kenvp;
|
||||
* General function declarations.
|
||||
*/
|
||||
|
||||
struct inpcb;
|
||||
struct lock_object;
|
||||
struct malloc_type;
|
||||
struct mtx;
|
||||
@ -227,6 +228,7 @@ void cpu_stopprofclock(void);
|
||||
|
||||
int cr_cansee(struct ucred *u1, struct ucred *u2);
|
||||
int cr_canseesocket(struct ucred *cred, struct socket *so);
|
||||
int cr_canseeinpcb(struct ucred *cred, struct inpcb *inp);
|
||||
|
||||
char *getenv(const char *name);
|
||||
void freeenv(char *env);
|
||||
|
Loading…
Reference in New Issue
Block a user