Lines 1085-1091
linux_sendmsg_common(struct thread *td, l_int s, struc
Link Here
|
1085 |
l_uint flags) |
1085 |
l_uint flags) |
1086 |
{ |
1086 |
{ |
1087 |
struct cmsghdr *cmsg; |
1087 |
struct cmsghdr *cmsg; |
1088 |
struct cmsgcred cmcred; |
|
|
1089 |
struct mbuf *control; |
1088 |
struct mbuf *control; |
1090 |
struct msghdr msg; |
1089 |
struct msghdr msg; |
1091 |
struct l_cmsghdr linux_cmsg; |
1090 |
struct l_cmsghdr linux_cmsg; |
Lines 1096-1101
linux_sendmsg_common(struct thread *td, l_int s, struc
Link Here
|
1096 |
struct sockaddr *sa; |
1095 |
struct sockaddr *sa; |
1097 |
sa_family_t sa_family; |
1096 |
sa_family_t sa_family; |
1098 |
void *data; |
1097 |
void *data; |
|
|
1098 |
l_size_t len; |
1099 |
int error; |
1099 |
int error; |
1100 |
|
1100 |
|
1101 |
error = copyin(msghdr, &linux_msg, sizeof(linux_msg)); |
1101 |
error = copyin(msghdr, &linux_msg, sizeof(linux_msg)); |
Lines 1126-1132
linux_sendmsg_common(struct thread *td, l_int s, struc
Link Here
|
1126 |
return (error); |
1126 |
return (error); |
1127 |
|
1127 |
|
1128 |
control = NULL; |
1128 |
control = NULL; |
1129 |
cmsg = NULL; |
|
|
1130 |
|
1129 |
|
1131 |
if ((ptr_cmsg = LINUX_CMSG_FIRSTHDR(&linux_msg)) != NULL) { |
1130 |
if ((ptr_cmsg = LINUX_CMSG_FIRSTHDR(&linux_msg)) != NULL) { |
1132 |
error = kern_getsockname(td, s, &sa, &datalen); |
1131 |
error = kern_getsockname(td, s, &sa, &datalen); |
Lines 1136-1143
linux_sendmsg_common(struct thread *td, l_int s, struc
Link Here
|
1136 |
free(sa, M_SONAME); |
1135 |
free(sa, M_SONAME); |
1137 |
|
1136 |
|
1138 |
error = ENOBUFS; |
1137 |
error = ENOBUFS; |
1139 |
cmsg = malloc(CMSG_HDRSZ, M_LINUX, M_WAITOK|M_ZERO); |
|
|
1140 |
control = m_get(M_WAITOK, MT_CONTROL); |
1138 |
control = m_get(M_WAITOK, MT_CONTROL); |
|
|
1139 |
MCLGET(control, M_WAITOK); |
1140 |
data = mtod(control, void *); |
1141 |
datalen = 0; |
1141 |
|
1142 |
|
1142 |
do { |
1143 |
do { |
1143 |
error = copyin(ptr_cmsg, &linux_cmsg, |
1144 |
error = copyin(ptr_cmsg, &linux_cmsg, |
Lines 1149-1158
linux_sendmsg_common(struct thread *td, l_int s, struc
Link Here
|
1149 |
if (linux_cmsg.cmsg_len < sizeof(struct l_cmsghdr)) |
1150 |
if (linux_cmsg.cmsg_len < sizeof(struct l_cmsghdr)) |
1150 |
goto bad; |
1151 |
goto bad; |
1151 |
|
1152 |
|
|
|
1153 |
if (datalen + CMSG_HDRSZ > MCLBYTES) |
1154 |
goto bad; |
1155 |
|
1152 |
/* |
1156 |
/* |
1153 |
* Now we support only SCM_RIGHTS and SCM_CRED, |
1157 |
* Now we support only SCM_RIGHTS and SCM_CRED, |
1154 |
* so return EINVAL in any other cmsg_type |
1158 |
* so return EINVAL in any other cmsg_type |
1155 |
*/ |
1159 |
*/ |
|
|
1160 |
cmsg = data; |
1156 |
cmsg->cmsg_type = |
1161 |
cmsg->cmsg_type = |
1157 |
linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type); |
1162 |
linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type); |
1158 |
cmsg->cmsg_level = |
1163 |
cmsg->cmsg_level = |
Lines 1170-1204
linux_sendmsg_common(struct thread *td, l_int s, struc
Link Here
|
1170 |
if (sa_family != AF_UNIX) |
1175 |
if (sa_family != AF_UNIX) |
1171 |
continue; |
1176 |
continue; |
1172 |
|
1177 |
|
1173 |
data = LINUX_CMSG_DATA(ptr_cmsg); |
1178 |
if (cmsg->cmsg_type == SCM_CREDS) { |
1174 |
datalen = linux_cmsg.cmsg_len - L_CMSG_HDRSZ; |
1179 |
len = sizeof(struct cmsgcred); |
|
|
1180 |
if (datalen + CMSG_SPACE(len) > MCLBYTES) |
1181 |
goto bad; |
1175 |
|
1182 |
|
1176 |
switch (cmsg->cmsg_type) |
|
|
1177 |
{ |
1178 |
case SCM_RIGHTS: |
1179 |
break; |
1180 |
|
1181 |
case SCM_CREDS: |
1182 |
data = &cmcred; |
1183 |
datalen = sizeof(cmcred); |
1184 |
|
1185 |
/* |
1183 |
/* |
1186 |
* The lower levels will fill in the structure |
1184 |
* The lower levels will fill in the structure |
1187 |
*/ |
1185 |
*/ |
1188 |
bzero(data, datalen); |
1186 |
memset(CMSG_DATA(data), 0, len); |
1189 |
break; |
1187 |
} else { |
|
|
1188 |
len = linux_cmsg.cmsg_len - L_CMSG_HDRSZ; |
1189 |
if (datalen + CMSG_SPACE(len) < datalen || |
1190 |
datalen + CMSG_SPACE(len) > MCLBYTES) |
1191 |
goto bad; |
1192 |
|
1193 |
error = copyin(LINUX_CMSG_DATA(ptr_cmsg), |
1194 |
CMSG_DATA(data), len); |
1195 |
if (error != 0) |
1196 |
goto bad; |
1190 |
} |
1197 |
} |
1191 |
|
1198 |
|
1192 |
cmsg->cmsg_len = CMSG_LEN(datalen); |
1199 |
cmsg->cmsg_len = CMSG_LEN(len); |
1193 |
|
1200 |
data = (char *)data + CMSG_SPACE(len); |
1194 |
error = ENOBUFS; |
1201 |
datalen += CMSG_SPACE(len); |
1195 |
if (!m_append(control, CMSG_HDRSZ, (c_caddr_t)cmsg)) |
|
|
1196 |
goto bad; |
1197 |
if (!m_append(control, datalen, (c_caddr_t)data)) |
1198 |
goto bad; |
1199 |
} while ((ptr_cmsg = LINUX_CMSG_NXTHDR(&linux_msg, ptr_cmsg))); |
1202 |
} while ((ptr_cmsg = LINUX_CMSG_NXTHDR(&linux_msg, ptr_cmsg))); |
1200 |
|
1203 |
|
1201 |
if (m_length(control, NULL) == 0) { |
1204 |
control->m_len = datalen; |
|
|
1205 |
if (datalen == 0) { |
1202 |
m_freem(control); |
1206 |
m_freem(control); |
1203 |
control = NULL; |
1207 |
control = NULL; |
1204 |
} |
1208 |
} |
Lines 1212-1219
linux_sendmsg_common(struct thread *td, l_int s, struc
Link Here
|
1212 |
bad: |
1216 |
bad: |
1213 |
m_freem(control); |
1217 |
m_freem(control); |
1214 |
free(iov, M_IOV); |
1218 |
free(iov, M_IOV); |
1215 |
if (cmsg) |
|
|
1216 |
free(cmsg, M_LINUX); |
1217 |
return (error); |
1219 |
return (error); |
1218 |
} |
1220 |
} |
1219 |
|
1221 |
|