|
4 | 4 |
|
5 | 5 | import os
|
6 | 6 | import shutil
|
| 7 | +import stat |
7 | 8 |
|
8 | 9 | from subprocess import run, PIPE
|
9 | 10 |
|
@@ -119,19 +120,24 @@ def chroot_path(self):
|
119 | 120 | return os.path.join(self.chroot_base_with_id(), 'root')
|
120 | 121 |
|
121 | 122 | def jailed_path(self, file_path, create=False, create_jail=False):
|
122 |
| - """Create a hard link owned by uid:gid. |
| 123 | + """Create a hard link or block special device owned by uid:gid. |
123 | 124 |
|
124 |
| - Create a hard link to the specified file, changes the owner to |
125 |
| - uid:gid, and returns a path to the link which is valid within the jail. |
| 125 | + Create a hard link or block special device from the specified file, changes the owner to |
| 126 | + uid:gid, and returns a path to the file which is valid within the jail. |
126 | 127 | """
|
127 | 128 | file_name = os.path.basename(file_path)
|
128 | 129 | global_p = os.path.join(self.chroot_path(), file_name)
|
129 | 130 | if create_jail:
|
130 | 131 | os.makedirs(self.chroot_path(), exist_ok=True)
|
131 | 132 | jailed_p = os.path.join("/", file_name)
|
132 | 133 | if create:
|
133 |
| - cmd = 'ln -f {} {}'.format(file_path, global_p) |
134 |
| - run(cmd, shell=True, check=True) |
| 134 | + stat_result = os.stat(file_path) |
| 135 | + if stat.S_ISBLK(stat_result.st_mode): |
| 136 | + cmd = ['mknod', global_p, 'b', str(os.major(stat_result.st_rdev)), str(os.minor(stat_result.st_rdev))] |
| 137 | + run(cmd, check=True) |
| 138 | + else: |
| 139 | + cmd = 'ln -f {} {}'.format(file_path, global_p) |
| 140 | + run(cmd, shell=True, check=True) |
135 | 141 | cmd = 'chown {}:{} {}'.format(self.uid, self.gid, global_p)
|
136 | 142 | run(cmd, shell=True, check=True)
|
137 | 143 | return jailed_p
|
|
0 commit comments