View | Details | Raw Unified | Return to bug 149168
Collapse All | Expand All

(-)./compat/linux/linux_misc.h (+2 lines)
Lines 37-42 Link Here
37
					 * Second arg is a ptr to return the
37
					 * Second arg is a ptr to return the
38
					 * signal.
38
					 * signal.
39
					 */
39
					 */
40
#define	LINUX_PR_GET_KEEPCAPS	7	/* Get drop capabilities on setuid */
41
#define	LINUX_PR_SET_KEEPCAPS	8	/* Set drop capabilities on setuid */
40
#define	LINUX_PR_SET_NAME	15	/* Set process name. */
42
#define	LINUX_PR_SET_NAME	15	/* Set process name. */
41
#define	LINUX_PR_GET_NAME	16	/* Get process name. */
43
#define	LINUX_PR_GET_NAME	16	/* Get process name. */
42
44
(-)./compat/linux/linux_misc.c (+86 lines)
Lines 1733-1738 linux_exit_group(struct thread *td, stru Link Here
1733
	return (0);
1733
	return (0);
1734
}
1734
}
1735
1735
1736
#define _LINUX_CAPABILITY_VERSION  0x19980330
1737
1738
struct l_user_cap_header {
1739
	l_int	version;
1740
	l_int	pid;
1741
};
1742
1743
struct l_user_cap_data {
1744
	l_int	effective;
1745
	l_int	permitted;
1746
	l_int	inheritable;
1747
};
1748
1749
int
1750
linux_capget(struct thread *td, struct linux_capget_args *args)
1751
{
1752
	struct l_user_cap_header luch;
1753
	struct l_user_cap_data lucd;
1754
	int error;
1755
1756
	if (! args->hdrp)
1757
		return (EFAULT);
1758
1759
	error = copyin(args->hdrp, &luch, sizeof(luch));
1760
	if (error != 0)
1761
		return (error);
1762
1763
	if (luch.version != _LINUX_CAPABILITY_VERSION) {
1764
		luch.version = _LINUX_CAPABILITY_VERSION;
1765
		error = copyout(&luch, args->hdrp, sizeof(luch));
1766
		if (error)
1767
			return (error);
1768
		return (EINVAL);
1769
	}
1770
1771
	if (luch.pid)
1772
		return (EPERM);
1773
1774
	if (args->datap) {
1775
		bzero (&lucd, sizeof(lucd));
1776
		error = copyout(&lucd, args->datap, sizeof(lucd));
1777
	}
1778
1779
	return (error);
1780
}
1781
1782
int
1783
linux_capset(struct thread *td, struct linux_capset_args *args)
1784
{
1785
	struct l_user_cap_header luch;
1786
	struct l_user_cap_data lucd;
1787
	int error;
1788
1789
	if (! args->hdrp || ! args->datap)
1790
		return (EFAULT);
1791
1792
	error = copyin(args->hdrp, &luch, sizeof(luch));
1793
	if (error != 0)
1794
		return (error);
1795
1796
	if (luch.version != _LINUX_CAPABILITY_VERSION) {
1797
		luch.version = _LINUX_CAPABILITY_VERSION;
1798
		error = copyout(&luch, args->hdrp, sizeof(luch));
1799
		if (error)
1800
			return (error);
1801
		return (EINVAL);
1802
	}
1803
1804
	if (luch.pid)
1805
		return (EPERM);
1806
1807
	error = copyin(args->datap, &lucd, sizeof(lucd));
1808
	if (error != 0)
1809
		return (error);
1810
1811
	if (lucd.effective || lucd.permitted || lucd.inheritable)
1812
		return (EPERM);
1813
1814
	return (0);
1815
}
1816
1736
int
1817
int
1737
linux_prctl(struct thread *td, struct linux_prctl_args *args)
1818
linux_prctl(struct thread *td, struct linux_prctl_args *args)
1738
{
1819
{
Lines 1766-1771 linux_prctl(struct thread *td, struct li Link Here
1766
		    (void *)(register_t)args->arg2,
1847
		    (void *)(register_t)args->arg2,
1767
		    sizeof(pdeath_signal));
1848
		    sizeof(pdeath_signal));
1768
		break;
1849
		break;
1850
	case LINUX_PR_GET_KEEPCAPS:
1851
		td->td_retval[0] = 0;
1852
		break;
1853
	case LINUX_PR_SET_KEEPCAPS:
1854
		break;
1769
	case LINUX_PR_SET_NAME:
1855
	case LINUX_PR_SET_NAME:
1770
		/*
1856
		/*
1771
		 * To be on the safe side we need to make sure to not
1857
		 * To be on the safe side we need to make sure to not
(-)./compat/linux/linux_socket.h (+1 lines)
Lines 53-58 Link Here
53
/* Socket-level control message types */
53
/* Socket-level control message types */
54
54
55
#define LINUX_SCM_RIGHTS	0x01
55
#define LINUX_SCM_RIGHTS	0x01
56
#define LINUX_SCM_CREDENTIALS   0x02
56
57
57
/* Ancilliary data object information macros */
58
/* Ancilliary data object information macros */
58
59
(-)./compat/linux/linux_socket.c (-41 / +109 lines)
Lines 433-438 linux_to_bsd_cmsg_type(int cmsg_type) Link Here
433
	switch (cmsg_type) {
433
	switch (cmsg_type) {
434
	case LINUX_SCM_RIGHTS:
434
	case LINUX_SCM_RIGHTS:
435
		return (SCM_RIGHTS);
435
		return (SCM_RIGHTS);
436
	case LINUX_SCM_CREDENTIALS:
437
		return (SCM_CREDS);
436
	}
438
	}
437
	return (-1);
439
	return (-1);
438
}
440
}
Lines 444-449 bsd_to_linux_cmsg_type(int cmsg_type) Link Here
444
	switch (cmsg_type) {
446
	switch (cmsg_type) {
445
	case SCM_RIGHTS:
447
	case SCM_RIGHTS:
446
		return (LINUX_SCM_RIGHTS);
448
		return (LINUX_SCM_RIGHTS);
449
	case SCM_CREDS:
450
		return (LINUX_SCM_CREDENTIALS);
447
	}
451
	}
448
	return (-1);
452
	return (-1);
449
}
453
}
Lines 472-478 bsd_to_linux_msghdr(const struct msghdr Link Here
472
	lhdr->msg_iov		= PTROUT(bhdr->msg_iov);
476
	lhdr->msg_iov		= PTROUT(bhdr->msg_iov);
473
	lhdr->msg_iovlen	= bhdr->msg_iovlen;
477
	lhdr->msg_iovlen	= bhdr->msg_iovlen;
474
	lhdr->msg_control	= PTROUT(bhdr->msg_control);
478
	lhdr->msg_control	= PTROUT(bhdr->msg_control);
475
	lhdr->msg_controllen	= bhdr->msg_controllen;
479
	/* msg_controllen skipped */
476
	/* msg_flags skipped */
480
	/* msg_flags skipped */
477
	return (0);
481
	return (0);
478
}
482
}
Lines 1092-1097 static int Link Here
1092
linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
1096
linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
1093
{
1097
{
1094
	struct cmsghdr *cmsg;
1098
	struct cmsghdr *cmsg;
1099
	struct cmsgcred cmcred;
1095
	struct mbuf *control;
1100
	struct mbuf *control;
1096
	struct msghdr msg;
1101
	struct msghdr msg;
1097
	struct l_cmsghdr linux_cmsg;
1102
	struct l_cmsghdr linux_cmsg;
Lines 1099-1104 linux_sendmsg(struct thread *td, struct Link Here
1099
	struct l_msghdr linux_msg;
1104
	struct l_msghdr linux_msg;
1100
	struct iovec *iov;
1105
	struct iovec *iov;
1101
	socklen_t datalen;
1106
	socklen_t datalen;
1107
	struct sockaddr *sa;
1108
	sa_family_t sa_family;
1102
	void *data;
1109
	void *data;
1103
	int error;
1110
	int error;
1104
1111
Lines 1128-1134 linux_sendmsg(struct thread *td, struct Link Here
1128
	if (error)
1135
	if (error)
1129
		return (error);
1136
		return (error);
1130
1137
1138
	control = NULL;
1139
	cmsg = NULL;
1140
1131
	if (msg.msg_control != NULL) {
1141
	if (msg.msg_control != NULL) {
1142
		error = kern_getsockname(td, args->s, &sa, &datalen);
1143
		if (error)
1144
			goto bad;
1145
		sa_family = sa->sa_family;
1146
		free(sa, M_SONAME);
1147
1132
		error = ENOBUFS;
1148
		error = ENOBUFS;
1133
		cmsg = malloc(CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO);
1149
		cmsg = malloc(CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO);
1134
		control = m_get(M_WAIT, MT_CONTROL);
1150
		control = m_get(M_WAIT, MT_CONTROL);
Lines 1147-1164 linux_sendmsg(struct thread *td, struct Link Here
1147
				goto bad;
1163
				goto bad;
1148
1164
1149
			/*
1165
			/*
1150
			 * Now we support only SCM_RIGHTS, so return EINVAL
1166
			 * Now we support only SCM_RIGHTS and SCM_CRED,
1151
			 * in any other cmsg_type
1167
			 * so return EINVAL in any other cmsg_type
1152
			 */
1168
			 */
1153
			if ((cmsg->cmsg_type =
1169
			cmsg->cmsg_type =
1154
			    linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type)) == -1)
1170
			    linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type);
1155
				goto bad;
1156
			cmsg->cmsg_level =
1171
			cmsg->cmsg_level =
1157
			    linux_to_bsd_sockopt_level(linux_cmsg.cmsg_level);
1172
			    linux_to_bsd_sockopt_level(linux_cmsg.cmsg_level);
1173
			if (cmsg->cmsg_type == -1
1174
			    || cmsg->cmsg_level != SOL_SOCKET)
1175
				goto bad;
1176
1177
			/*
1178
			 * Some applications (e.g. pulseaudio) attempt to
1179
			 * send ancillary data even if the underlying protocol
1180
			 * doesn't support it which is not allowed in the
1181
			 * FreeBSD system call interface.
1182
			 */
1183
			if (sa_family != AF_UNIX)
1184
				continue;
1158
1185
1186
			data = LINUX_CMSG_DATA(ptr_cmsg);
1159
			datalen = linux_cmsg.cmsg_len - L_CMSG_HDRSZ;
1187
			datalen = linux_cmsg.cmsg_len - L_CMSG_HDRSZ;
1188
1189
			switch (cmsg->cmsg_type)
1190
			{
1191
			case SCM_RIGHTS:
1192
				break;
1193
1194
			case SCM_CREDS:
1195
				data = &cmcred;
1196
				datalen = sizeof(cmcred);
1197
1198
				/*
1199
				 * The lower levels will fill in the structure
1200
				 */
1201
				bzero(data, datalen);
1202
				break;
1203
			}
1204
1160
			cmsg->cmsg_len = CMSG_LEN(datalen);
1205
			cmsg->cmsg_len = CMSG_LEN(datalen);
1161
			data = LINUX_CMSG_DATA(ptr_cmsg);
1162
1206
1163
			error = ENOBUFS;
1207
			error = ENOBUFS;
1164
			if (!m_append(control, CMSG_HDRSZ, (c_caddr_t) cmsg))
1208
			if (!m_append(control, CMSG_HDRSZ, (c_caddr_t) cmsg))
Lines 1166-1174 linux_sendmsg(struct thread *td, struct Link Here
1166
			if (!m_append(control, datalen, (c_caddr_t) data))
1210
			if (!m_append(control, datalen, (c_caddr_t) data))
1167
				goto bad;
1211
				goto bad;
1168
		} while ((ptr_cmsg = LINUX_CMSG_NXTHDR(&msg, ptr_cmsg)));
1212
		} while ((ptr_cmsg = LINUX_CMSG_NXTHDR(&msg, ptr_cmsg)));
1169
	} else {
1213
1170
		control = NULL;
1214
		if (m_length(control, NULL) == 0) {
1171
		cmsg = NULL;
1215
			m_freem(control);
1216
			control = NULL;
1217
		}
1172
	}
1218
	}
1173
1219
1174
	msg.msg_iov = iov;
1220
	msg.msg_iov = iov;
Lines 1193-1201 static int Link Here
1193
linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
1239
linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
1194
{
1240
{
1195
	struct cmsghdr *cm;
1241
	struct cmsghdr *cm;
1242
	struct cmsgcred *cmcred;
1196
	struct msghdr msg;
1243
	struct msghdr msg;
1197
	struct l_cmsghdr *linux_cmsg = NULL;
1244
	struct l_cmsghdr *linux_cmsg = NULL;
1198
	socklen_t datalen, outlen, clen;
1245
	struct l_ucred linux_ucred;
1246
	socklen_t datalen, outlen;
1199
	struct l_msghdr linux_msg;
1247
	struct l_msghdr linux_msg;
1200
	struct iovec *iov, *uiov;
1248
	struct iovec *iov, *uiov;
1201
	struct mbuf *control = NULL;
1249
	struct mbuf *control = NULL;
Lines 1252-1290 linux_recvmsg(struct thread *td, struct Link Here
1252
			goto bad;
1300
			goto bad;
1253
	}
1301
	}
1254
1302
1255
	if (control) {
1303
	outbuf = PTRIN(linux_msg.msg_control);
1304
	outlen = 0;
1256
1305
1306
	if (control) {
1257
		linux_cmsg = malloc(L_CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO);
1307
		linux_cmsg = malloc(L_CMSG_HDRSZ, M_TEMP, M_WAITOK | M_ZERO);
1258
		outbuf = PTRIN(linux_msg.msg_control);
1259
		cm = mtod(control, struct cmsghdr *);
1260
		outlen = 0;
1261
		clen = control->m_len;
1262
1308
1263
		while (cm != NULL) {
1309
		msg.msg_control = mtod(control, struct cmsghdr *);
1310
		msg.msg_controllen = control->m_len;
1311
1312
		cm = CMSG_FIRSTHDR(&msg);
1264
1313
1265
			if ((linux_cmsg->cmsg_type =
1314
		while (cm != NULL) {
1266
			    bsd_to_linux_cmsg_type(cm->cmsg_type)) == -1)
1315
			linux_cmsg->cmsg_type =
1316
			    bsd_to_linux_cmsg_type(cm->cmsg_type);
1317
			linux_cmsg->cmsg_level =
1318
			    bsd_to_linux_sockopt_level(cm->cmsg_level);
1319
			if (linux_cmsg->cmsg_type == -1
1320
			    || cm->cmsg_level != SOL_SOCKET)
1267
			{
1321
			{
1268
				error = EINVAL;
1322
				error = EINVAL;
1269
				goto bad;
1323
				goto bad;
1270
			}
1324
			}
1325
1271
			data = CMSG_DATA(cm);
1326
			data = CMSG_DATA(cm);
1272
			datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1327
			datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1273
1328
1274
			switch (linux_cmsg->cmsg_type)
1329
			switch (cm->cmsg_type)
1275
			{
1330
			{
1276
			case LINUX_SCM_RIGHTS:
1331
			case SCM_RIGHTS:
1277
				if (outlen + LINUX_CMSG_LEN(datalen) >
1278
				    linux_msg.msg_controllen) {
1279
					if (outlen == 0) {
1280
						error = EMSGSIZE;
1281
						goto bad;
1282
					} else {
1283
						linux_msg.msg_flags |=
1284
						    LINUX_MSG_CTRUNC;
1285
						goto out;
1286
					}
1287
				}
1288
				if (args->flags & LINUX_MSG_CMSG_CLOEXEC) {
1332
				if (args->flags & LINUX_MSG_CMSG_CLOEXEC) {
1289
					fds = datalen / sizeof(int);
1333
					fds = datalen / sizeof(int);
1290
					fdp = data;
1334
					fdp = data;
Lines 1295-1305 linux_recvmsg(struct thread *td, struct Link Here
1295
					}
1339
					}
1296
				}
1340
				}
1297
				break;
1341
				break;
1342
1343
			case SCM_CREDS:
1344
				/*
1345
				 * Currently LOCAL_CREDS is never in
1346
				 * effect for Linux so no need to worry
1347
				 * about sockcred
1348
				 */
1349
				if (datalen != sizeof (*cmcred)) {
1350
					error = EMSGSIZE;
1351
					goto bad;
1352
				}
1353
				cmcred = (struct cmsgcred *)data;
1354
				bzero(&linux_ucred, sizeof(linux_ucred));
1355
				linux_ucred.pid = cmcred->cmcred_pid;
1356
				linux_ucred.uid = cmcred->cmcred_uid;
1357
				linux_ucred.gid = cmcred->cmcred_gid;
1358
				data = &linux_ucred;
1359
				datalen = sizeof(linux_ucred);
1360
				break;
1361
			}
1362
1363
			if (outlen + LINUX_CMSG_LEN(datalen) >
1364
			    linux_msg.msg_controllen) {
1365
				if (outlen == 0) {
1366
					error = EMSGSIZE;
1367
					goto bad;
1368
				} else {
1369
					linux_msg.msg_flags |=
1370
					    LINUX_MSG_CTRUNC;
1371
					goto out;
1372
				}
1298
			}
1373
			}
1299
1374
1300
			linux_cmsg->cmsg_len = LINUX_CMSG_LEN(datalen);
1375
			linux_cmsg->cmsg_len = LINUX_CMSG_LEN(datalen);
1301
			linux_cmsg->cmsg_level =
1302
			    bsd_to_linux_sockopt_level(cm->cmsg_level);
1303
1376
1304
			error = copyout(linux_cmsg, outbuf, L_CMSG_HDRSZ);
1377
			error = copyout(linux_cmsg, outbuf, L_CMSG_HDRSZ);
1305
			if (error)
1378
			if (error)
Lines 1312-1329 linux_recvmsg(struct thread *td, struct Link Here
1312
1385
1313
			outbuf += LINUX_CMSG_ALIGN(datalen);
1386
			outbuf += LINUX_CMSG_ALIGN(datalen);
1314
			outlen += LINUX_CMSG_LEN(datalen);
1387
			outlen += LINUX_CMSG_LEN(datalen);
1315
			linux_msg.msg_controllen = outlen;
1316
1388
1317
			if (CMSG_SPACE(datalen) < clen) {
1389
			cm = CMSG_NXTHDR(&msg, cm);
1318
				clen -= CMSG_SPACE(datalen);
1319
				cm = (struct cmsghdr *)
1320
				    ((caddr_t)cm + CMSG_SPACE(datalen));
1321
			} else
1322
				cm = NULL;
1323
		}
1390
		}
1324
	}
1391
	}
1325
1392
1326
out:
1393
out:
1394
	linux_msg.msg_controllen = outlen;
1327
	error = copyout(&linux_msg, PTRIN(args->msg), sizeof(linux_msg));
1395
	error = copyout(&linux_msg, PTRIN(args->msg), sizeof(linux_msg));
1328
1396
1329
bad:
1397
bad:
(-)./i386/linux/linux_proto.h (-2 / +4 lines)
Lines 586-595 struct linux_getcwd_args { Link Here
586
	char bufsize_l_[PADL_(l_ulong)]; l_ulong bufsize; char bufsize_r_[PADR_(l_ulong)];
586
	char bufsize_l_[PADL_(l_ulong)]; l_ulong bufsize; char bufsize_r_[PADR_(l_ulong)];
587
};
587
};
588
struct linux_capget_args {
588
struct linux_capget_args {
589
	register_t dummy;
589
	char hdrp_l_[PADL_(void *)]; void * hdrp; char hdrp_r_[PADR_(void *)];
590
	char datap_l_[PADL_(void *)]; void * datap; char datap_r_[PADR_(void *)];
590
};
591
};
591
struct linux_capset_args {
592
struct linux_capset_args {
592
	register_t dummy;
593
	char hdrp_l_[PADL_(void *)]; void * hdrp; char hdrp_r_[PADR_(void *)];
594
	char datap_l_[PADL_(void *)]; void * datap; char datap_r_[PADR_(void *)];
593
};
595
};
594
struct linux_sigaltstack_args {
596
struct linux_sigaltstack_args {
595
	char uss_l_[PADL_(l_stack_t *)]; l_stack_t * uss; char uss_r_[PADR_(l_stack_t *)];
597
	char uss_l_[PADL_(l_stack_t *)]; l_stack_t * uss; char uss_r_[PADR_(l_stack_t *)];
(-)./i386/linux/linux_dummy.c (-2 lines)
Lines 57-64 DUMMY(vm86); Link Here
57
DUMMY(query_module);
57
DUMMY(query_module);
58
DUMMY(nfsservctl);
58
DUMMY(nfsservctl);
59
DUMMY(rt_sigqueueinfo);
59
DUMMY(rt_sigqueueinfo);
60
DUMMY(capget);
61
DUMMY(capset);
62
DUMMY(sendfile);		/* different semantics */
60
DUMMY(sendfile);		/* different semantics */
63
DUMMY(setfsuid);
61
DUMMY(setfsuid);
64
DUMMY(setfsgid);
62
DUMMY(setfsgid);

Return to bug 149168