Push down the major/minor conversion for pts/%u to improve consistency.

In the mpsafetty branch, Linux sshd seems to work properly inside a
jail. Some small modifications had to be made to the Linux compatibility
layer.

The Linux PTY routines always expect the device major number to be 136
or higher. Our code always set the major/minor number pair to 136:0.
This makes routines like ttyname() and ptsname() fail, because we'll end
up having ambiguous device numbers.

The conversion was not performed on all *stat() routines, which meant in
some cases the numbers didn't get transformed. By pushing the conversion
into linux_driver_get_major_minor(), the transformation will take place
on all calls.

Approved by:	philip (mentor), rdivacky
This commit is contained in:
ed 2008-06-02 08:40:06 +00:00
parent b3629efe71
commit ff609f1187
2 changed files with 20 additions and 26 deletions

View File

@ -178,19 +178,8 @@ linux_newstat(struct thread *td, struct linux_newstat_args *args)
#endif
error = kern_stat(td, path, UIO_SYSSPACE, &buf);
if (!error) {
if (strlen(path) > strlen("/dev/pts/") &&
!strncmp(path, "/dev/pts/", strlen("/dev/pts/")) &&
path[9] >= '0' && path[9] <= '9') {
/*
* Linux checks major and minors of the slave device
* to make sure it's a pty device, so let's make him
* believe it is.
*/
buf.st_rdev = (136 << 8);
} else
translate_path_major_minor(td, path, &buf);
}
if (!error)
translate_path_major_minor(td, path, &buf);
LFREEPATH(path);
if (error)
return (error);
@ -528,19 +517,8 @@ linux_stat64(struct thread *td, struct linux_stat64_args *args)
#endif
error = kern_stat(td, filename, UIO_SYSSPACE, &buf);
if (!error) {
if (strlen(filename) > strlen("/dev/pts/") &&
!strncmp(filename, "/dev/pts/", strlen("/dev/pts/")) &&
filename[9] >= '0' && filename[9] <= '9') {
/*
* Linux checks major and minors of the slave device
* to make sure it's a pty deivce, so let's make him
* believe it is.
*/
buf.st_rdev = (136 << 8);
} else
translate_path_major_minor(td, filename, &buf);
}
if (!error)
translate_path_major_minor(td, filename, &buf);
LFREEPATH(filename);
if (error)
return (error);

View File

@ -130,6 +130,22 @@ linux_driver_get_major_minor(char *node, int *major, int *minor)
if (node == NULL || major == NULL || minor == NULL)
return 1;
if (strlen(node) > strlen("pts/") &&
strncmp(node, "pts/", strlen("pts/")) == 0) {
unsigned long devno;
/*
* Linux checks major and minors of the slave device
* to make sure it's a pty device, so let's make him
* believe it is.
*/
devno = strtoul(node + strlen("pts/"), NULL, 10);
*major = 136 + (devno / 256);
*minor = devno % 256;
return 0;
}
TAILQ_FOREACH(de, &devices, list) {
if (strcmp(node, de->entry.bsd_device_name) == 0) {
*major = de->entry.linux_major;