Skip to content

Commit

Permalink
xnu-4903.241.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jan 11, 2021
1 parent cecb6e5 commit f8fc7be
Show file tree
Hide file tree
Showing 20 changed files with 603 additions and 403 deletions.
4 changes: 4 additions & 0 deletions bsd/kern/kern_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -5986,9 +5986,11 @@ kqueue_threadreq_initiate(struct kqueue *kq, struct kqrequest *kqr,
* Provide the pthread kext a pointer to a workq_threadreq_s structure for
* its use until a corresponding kqueue_threadreq_bind callback.
*/
#if 0 // 45129862
if ((kq->kq_state & KQ_WORKLOOP) && current_proc() == kq->kq_p) {
flags |= WORKQ_THREADREQ_SET_AST_ON_FAILURE;
}
#endif
if (qos == KQWQ_QOS_MANAGER) {
qos = WORKQ_THREAD_QOS_MANAGER;
}
Expand Down Expand Up @@ -6062,9 +6064,11 @@ kqueue_threadreq_modify(struct kqueue *kq, struct kqrequest *kqr, kq_index_t qos
kq_req_held(kq);

int flags = 0;
#if 0 // 45129862
if ((kq->kq_state & KQ_WORKLOOP) && kq->kq_p == current_proc()) {
flags |= WORKQ_THREADREQ_SET_AST_ON_FAILURE;
}
#endif
workq_kern_threadreq_modify(kq->kq_p, kqr, qos, flags);
}

Expand Down
2 changes: 1 addition & 1 deletion bsd/kern/ubc_subr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ errno_t ubc_setsize_ex(struct vnode *vp, off_t nsize, ubc_setsize_opts_t opts)
* zero the tail of this page if it's currently
* present in the cache
*/
kret = ubc_create_upl_kernel(vp, lastpg, PAGE_SIZE, &upl, &pl, UPL_SET_LITE, VM_KERN_MEMORY_FILE);
kret = ubc_create_upl_kernel(vp, lastpg, PAGE_SIZE, &upl, &pl, UPL_SET_LITE | UPL_WILL_MODIFY, VM_KERN_MEMORY_FILE);

if (kret != KERN_SUCCESS)
panic("ubc_setsize: ubc_create_upl (error = %d)\n", kret);
Expand Down
56 changes: 48 additions & 8 deletions bsd/net/if_ports_used.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ SYSCTL_PROC(_net_link_generic_system_port_used, OID_AUTO, list,

static int use_test_wakeuuid = 0;
static uuid_t test_wakeuuid;
static uuid_string_t test_wakeuuid_str;

#if (DEVELOPMENT || DEBUG)
SYSCTL_INT(_net_link_generic_system_port_used, OID_AUTO, use_test_wakeuuid,
Expand All @@ -88,6 +89,11 @@ SYSCTL_PROC(_net_link_generic_system_port_used, OID_AUTO, clear_test_wakeuuid,
CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0,
sysctl_clear_test_wakeuuid, "S,uuid_t", "");

int sysctl_test_wakeuuid_str SYSCTL_HANDLER_ARGS;
SYSCTL_PROC(_net_link_generic_system_port_used, OID_AUTO, test_wakeuuid_str,
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_LOCKED, 0, 0,
sysctl_test_wakeuuid_str, "A", "");

SYSCTL_OPAQUE(_net_link_generic_system_port_used, OID_AUTO, test_wakeuuid,
CTLFLAG_RD|CTLFLAG_LOCKED,
test_wakeuuid, sizeof(uuid_t), "S,uuid_t", "");
Expand Down Expand Up @@ -209,12 +215,17 @@ net_port_entry_list_clear(void)
}

static bool
get_test_wake_uuid(uuid_t wakeuuid)
get_test_wake_uuid(uuid_string_t wakeuuid_str, size_t len)
{
if (__improbable(use_test_wakeuuid)) {
if (!uuid_is_null(test_wakeuuid)) {
if (wakeuuid != NULL) {
uuid_copy(wakeuuid, test_wakeuuid);
if (wakeuuid_str != NULL && len != 0) {
uuid_unparse(test_wakeuuid, wakeuuid_str);
}
return (true);
} else if (strlen(test_wakeuuid_str) != 0) {
if (wakeuuid_str != NULL && len != 0) {
strlcpy(wakeuuid_str, test_wakeuuid_str, len);
}
return (true);
} else {
Expand All @@ -232,7 +243,7 @@ is_wakeuuid_set(void)
* IOPMCopySleepWakeUUIDKey() tells if SleepWakeUUID is currently set
* That means we are currently in a sleep/wake cycle
*/
return (get_test_wake_uuid(NULL) || IOPMCopySleepWakeUUIDKey(NULL, 0));
return (get_test_wake_uuid(NULL, 0) || IOPMCopySleepWakeUUIDKey(NULL, 0));
}

void
Expand All @@ -241,16 +252,25 @@ if_ports_used_update_wakeuuid(struct ifnet *ifp)
uuid_t wakeuuid;
bool wakeuuid_is_set = false;
bool updated = false;
uuid_string_t wakeuuid_str;

uuid_clear(wakeuuid);

if (__improbable(use_test_wakeuuid)) {
wakeuuid_is_set = get_test_wake_uuid(wakeuuid);
wakeuuid_is_set = get_test_wake_uuid(wakeuuid_str,
sizeof(wakeuuid_str));
} else {
uuid_string_t wakeuuid_str;

wakeuuid_is_set = IOPMCopySleepWakeUUIDKey(wakeuuid_str,
sizeof(wakeuuid_str));
if (wakeuuid_is_set) {
uuid_parse(wakeuuid_str, wakeuuid);
}

if (wakeuuid_is_set) {
if (uuid_parse(wakeuuid_str, wakeuuid) != 0) {
os_log(OS_LOG_DEFAULT,
"%s: IOPMCopySleepWakeUUIDKey got bad value %s\n",
__func__, wakeuuid_str);
wakeuuid_is_set = false;
}
}

Expand Down Expand Up @@ -446,13 +466,33 @@ sysctl_clear_test_wakeuuid SYSCTL_HANDLER_ARGS
}
if (req->newptr != USER_ADDR_NULL) {
uuid_clear(test_wakeuuid);
test_wakeuuid_str[0] = 0;
}
error = SYSCTL_OUT(req, test_wakeuuid,
MIN(sizeof(uuid_t), req->oldlen));

return (error);
}

int
sysctl_test_wakeuuid_str SYSCTL_HANDLER_ARGS
{
#pragma unused(oidp, arg1, arg2)
int error = 0;
int changed;

if (kauth_cred_issuser(kauth_cred_get()) == 0) {
return (EPERM);
}
error = sysctl_io_string(req, test_wakeuuid_str, sizeof(test_wakeuuid_str), 1, &changed);
if (changed) {
os_log_info(OS_LOG_DEFAULT, "%s: test_wakeuuid_str %s",
__func__, test_wakeuuid_str);
}

return (error);
}

#endif /* (DEVELOPMENT || DEBUG) */

int
Expand Down
26 changes: 14 additions & 12 deletions bsd/netinet/flow_divert.c
Original file line number Diff line number Diff line change
Expand Up @@ -1913,18 +1913,20 @@ flow_divert_handle_close(struct flow_divert_pcb *fd_cb, mbuf_t packet, int offse
static mbuf_t
flow_divert_get_control_mbuf(struct flow_divert_pcb *fd_cb)
{
struct inpcb *inp = sotoinpcb(fd_cb->so);
if (inp->inp_vflag & INP_IPV4 && inp->inp_flags & INP_RECVDSTADDR) {
struct sockaddr_in *sin = (struct sockaddr_in *)(void *)fd_cb->local_address;

return sbcreatecontrol((caddr_t) &sin->sin_addr, sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
} else if (inp->inp_vflag & INP_IPV6 && (inp->inp_flags & IN6P_PKTINFO) != 0) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(void *)fd_cb->local_address;
struct in6_pktinfo pi6;

bcopy(&sin6->sin6_addr, &pi6.ipi6_addr, sizeof (struct in6_addr));
pi6.ipi6_ifindex = 0;
return sbcreatecontrol((caddr_t)&pi6, sizeof (struct in6_pktinfo), IPV6_PKTINFO, IPPROTO_IPV6);
if (fd_cb->local_address != NULL) {
struct inpcb *inp = sotoinpcb(fd_cb->so);
if (inp->inp_vflag & INP_IPV4 && inp->inp_flags & INP_RECVDSTADDR) {
struct sockaddr_in *sin = (struct sockaddr_in *)(void *)fd_cb->local_address;

return sbcreatecontrol((caddr_t) &sin->sin_addr, sizeof(struct in_addr), IP_RECVDSTADDR, IPPROTO_IP);
} else if (inp->inp_vflag & INP_IPV6 && (inp->inp_flags & IN6P_PKTINFO) != 0) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)(void *)fd_cb->local_address;
struct in6_pktinfo pi6;

bcopy(&sin6->sin6_addr, &pi6.ipi6_addr, sizeof (struct in6_addr));
pi6.ipi6_ifindex = 0;
return sbcreatecontrol((caddr_t)&pi6, sizeof (struct in6_pktinfo), IPV6_PKTINFO, IPPROTO_IPV6);
}
}
return (NULL);
}
Expand Down
16 changes: 15 additions & 1 deletion bsd/netkey/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -7898,6 +7898,7 @@ static int
key_getsastatbyspi (struct sastat *stat_arg,
u_int32_t max_stat_arg,
struct sastat *stat_res,
u_int32_t stat_res_size,
u_int32_t *max_stat_res)
{
int cur, found = 0;
Expand All @@ -7907,8 +7908,11 @@ key_getsastatbyspi (struct sastat *stat_arg,
max_stat_res == NULL) {
return -1;
}

u_int32_t max_stats = stat_res_size / (sizeof(struct sastat));
max_stats = ((max_stat_arg <= max_stats) ? max_stat_arg : max_stats);

for (cur = 0; cur < max_stat_arg; cur++) {
for (cur = 0; cur < max_stats; cur++) {
if (key_getsastatbyspi_one(stat_arg[cur].spi,
&stat_res[found]) == 0) {
found++;
Expand Down Expand Up @@ -9863,6 +9867,15 @@ key_validate_ext(
return EINVAL;
break;
}

/* check key bits length */
if (ext->sadb_ext_type == SADB_EXT_KEY_AUTH ||
ext->sadb_ext_type == SADB_EXT_KEY_ENCRYPT) {
struct sadb_key *key = (struct sadb_key *)(uintptr_t)ext;
if (len < (sizeof(struct sadb_key) + _KEYLEN(key))) {
return EINVAL;
}
}

return 0;
}
Expand Down Expand Up @@ -10168,6 +10181,7 @@ key_getsastat (struct socket *so,
if (key_getsastatbyspi((struct sastat *)(sa_stats_arg + 1),
arg_count,
sa_stats_sav,
bufsize,
&res_count)) {
printf("%s: Error finding SAs.\n", __FUNCTION__);
error = ENOENT;
Expand Down
4 changes: 4 additions & 0 deletions bsd/security/audit/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ void audit_arg_auditinfo_addr(struct kaudit_record *ar,
struct auditinfo_addr *au_info);
void audit_arg_upath(struct kaudit_record *ar, struct vnode *cwd_vp,
char *upath, u_int64_t flags);
void audit_arg_kpath(struct kaudit_record *ar,
char *kpath, u_int64_t flags);
void audit_arg_vnpath(struct kaudit_record *ar, struct vnode *vp,
u_int64_t flags);
void audit_arg_vnpath_withref(struct kaudit_record *ar, struct vnode *vp,
Expand Down Expand Up @@ -317,6 +319,8 @@ extern au_event_t sys_au_event[];

#endif /* AUDIT_USE_BUILTIN_EXPECT */

#define AUDIT_RECORD_EXISTS() (AUDIT_ENABLED() && AUDIT_AUDITING(AUDIT_RECORD()))

/*
* Define a macro to wrap the audit_arg_* calls by checking the global
* audit_enabled flag before performing the actual call.
Expand Down
25 changes: 25 additions & 0 deletions bsd/security/audit/audit_arg.c
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,31 @@ audit_arg_upath(struct kaudit_record *ar, struct vnode *cwd_vp, char *upath, u_i
}
}

void
audit_arg_kpath(struct kaudit_record *ar, char *kpath, u_int64_t flag)
{
char **pathp;

KASSERT(kpath != NULL, ("audit_arg_kpath: kpath == NULL"));
KASSERT((flag == ARG_KPATH1) || (flag == ARG_KPATH2),
("audit_arg_kpath: flag %llu", (unsigned long long)flag));
KASSERT((flag != ARG_KPATH1) || (flag != ARG_KPATH2),
("audit_arg_kpath: flag %llu", (unsigned long long)flag));

if (flag == ARG_KPATH1)
pathp = &ar->k_ar.ar_arg_kpath1;
else
pathp = &ar->k_ar.ar_arg_kpath2;

if (*pathp == NULL)
*pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
else
return;

strlcpy(*pathp, kpath, MAXPATHLEN);
ARG_SET_VALID(ar, flag);
}

/*
* Function to save the path and vnode attr information into the audit
* record.
Expand Down
8 changes: 8 additions & 0 deletions bsd/security/audit/audit_bsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ kau_free(struct au_record *rec)
} \
} while (0)

#define KPATH2_TOKENS do { \
if (ARG_IS_VALID(kar, ARG_KPATH2)) { \
tok = au_to_path(ar->ar_arg_kpath2); \
kau_write(rec, tok); \
} \
} while (0)

#define VNODE1_TOKENS do { \
if (ARG_IS_VALID(kar, ARG_KPATH1)) { \
tok = au_to_path(ar->ar_arg_kpath1); \
Expand Down Expand Up @@ -1188,6 +1195,7 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
case AUE_RENAME:
UPATH1_VNODE1_TOKENS;
UPATH2_TOKENS;
KPATH2_TOKENS;
break;

case AUE_MKDIR_EXTENDED:
Expand Down
31 changes: 28 additions & 3 deletions bsd/vfs/vfs_syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -4375,7 +4375,7 @@ linkat_internal(vfs_context_t ctx, int fd1, user_addr_t path, int fd2,
#if CONFIG_FSE
fse_info finfo;
#endif
int need_event, has_listeners;
int need_event, has_listeners, need_kpath2;
char *target_path = NULL;
int truncated=0;

Expand Down Expand Up @@ -4471,7 +4471,14 @@ linkat_internal(vfs_context_t ctx, int fd1, user_addr_t path, int fd2,
#endif
has_listeners = kauth_authorize_fileop_has_listeners();

if (need_event || has_listeners) {
need_kpath2 = 0;
#if CONFIG_AUDIT
if (AUDIT_RECORD_EXISTS()) {
need_kpath2 = 1;
}
#endif

if (need_event || has_listeners || need_kpath2) {
char *link_to_path = NULL;
int len, link_name_len;

Expand All @@ -4484,6 +4491,8 @@ linkat_internal(vfs_context_t ctx, int fd1, user_addr_t path, int fd2,

len = safe_getpath(dvp, nd.ni_cnd.cn_nameptr, target_path, MAXPATHLEN, &truncated);

AUDIT_ARG(kpath, target_path, ARG_KPATH2);

if (has_listeners) {
/* build the path to file we are linking to */
GET_PATH(link_to_path);
Expand Down Expand Up @@ -7317,6 +7326,8 @@ renameat_internal(vfs_context_t ctx, int fromfd, user_addr_t from,
int retry_count;
int mntrename;
int need_event;
int need_kpath2;
int has_listeners;
const char *oname = NULL;
char *from_name = NULL, *to_name = NULL;
int from_len=0, to_len=0;
Expand Down Expand Up @@ -7439,7 +7450,16 @@ renameat_internal(vfs_context_t ctx, int fromfd, user_addr_t from,
need_event = 0;
#endif /* CONFIG_FSE */

if (need_event || kauth_authorize_fileop_has_listeners()) {
has_listeners = kauth_authorize_fileop_has_listeners();

need_kpath2 = 0;
#if CONFIG_AUDIT
if (AUDIT_RECORD_EXISTS()) {
need_kpath2 = 1;
}
#endif

if (need_event || has_listeners) {
if (from_name == NULL) {
GET_PATH(from_name);
if (from_name == NULL) {
Expand All @@ -7449,7 +7469,9 @@ renameat_internal(vfs_context_t ctx, int fromfd, user_addr_t from,
}

from_len = safe_getpath(fdvp, fromnd->ni_cnd.cn_nameptr, from_name, MAXPATHLEN, &from_truncated);
}

if (need_event || need_kpath2 || has_listeners) {
if (to_name == NULL) {
GET_PATH(to_name);
if (to_name == NULL) {
Expand All @@ -7459,6 +7481,9 @@ renameat_internal(vfs_context_t ctx, int fromfd, user_addr_t from,
}

to_len = safe_getpath(tdvp, tond->ni_cnd.cn_nameptr, to_name, MAXPATHLEN, &to_truncated);
if (to_name && need_kpath2) {
AUDIT_ARG(kpath, to_name, ARG_KPATH2);
}
}
if (!fvp) {
/*
Expand Down
Loading

0 comments on commit f8fc7be

Please sign in to comment.