@@ -35,52 +35,49 @@ var baseMounts = []*configs.Mount{
3535 Destination : "/dev/pts" ,
3636 Device : "devpts" ,
3737 Flags : syscall .MS_NOSUID | syscall .MS_NOEXEC ,
38- Data : "newinstance,ptmxmode=0666,mode=620 ,gid=5" ,
38+ Data : "newinstance,ptmxmode=0666,mode=0620 ,gid=5" ,
3939 },
4040}
4141
4242// setupRootfs sets up the devices, mount points, and filesystems for use inside a
4343// new mount namespace.
4444func setupRootfs (config * configs.Config ) (err error ) {
4545 if err := prepareRoot (config ); err != nil {
46- return err
46+ return newSystemError ( err )
4747 }
4848 for _ , m := range append (baseMounts , config .Mounts ... ) {
4949 if err := mount (m , config .Rootfs , config .MountLabel ); err != nil {
50- return err
50+ return newSystemError ( err )
5151 }
5252 }
5353 if err := createDevices (config ); err != nil {
54- return err
54+ return newSystemError ( err )
5555 }
5656 if err := setupPtmx (config ); err != nil {
57- return err
57+ return newSystemError ( err )
5858 }
5959 // stdin, stdout and stderr could be pointing to /dev/null from parent namespace.
60- // Re-open them inside this namespace.
61- // FIXME: Need to fix this for user namespaces.
62- if ! config .Namespaces .Contains (configs .NEWUSER ) {
63- if err := reOpenDevNull (config .Rootfs ); err != nil {
64- return err
65- }
60+ // re-open them inside this namespace.
61+ if err := reOpenDevNull (config .Rootfs ); err != nil {
62+ return newSystemError (err )
6663 }
6764 if err := setupDevSymlinks (config .Rootfs ); err != nil {
68- return err
65+ return newSystemError ( err )
6966 }
7067 if err := syscall .Chdir (config .Rootfs ); err != nil {
71- return err
68+ return newSystemError ( err )
7269 }
7370 if config .NoPivotRoot {
7471 err = msMoveRoot (config .Rootfs )
7572 } else {
7673 err = pivotRoot (config .Rootfs , config .PivotDir )
7774 }
7875 if err != nil {
79- return err
76+ return newSystemError ( err )
8077 }
8178 if config .Readonlyfs {
8279 if err := setReadonly (); err != nil {
83- return err
80+ return newSystemError ( err )
8481 }
8582 }
8683 syscall .Umask (0022 )
@@ -202,13 +199,32 @@ func createDevices(config *configs.Config) error {
202199
203200// Creates the device node in the rootfs of the container.
204201func createDeviceNode (rootfs string , node * configs.Device ) error {
205- var (
206- dest = filepath .Join (rootfs , node .Path )
207- parent = filepath .Dir (dest )
208- )
209- if err := os .MkdirAll (parent , 0755 ); err != nil {
202+ dest := filepath .Join (rootfs , node .Path )
203+ if err := os .MkdirAll (filepath .Dir (dest ), 0755 ); err != nil {
210204 return err
211205 }
206+ if err := mknodDevice (dest , node ); err != nil {
207+ if os .IsExist (err ) {
208+ return nil
209+ }
210+ if err != syscall .EPERM {
211+ return err
212+ }
213+ // containers running in a user namespace are not allowed to mknod
214+ // devices so we can just bind mount it from the host.
215+ f , err := os .Create (dest )
216+ if err != nil && ! os .IsExist (err ) {
217+ return err
218+ }
219+ if f != nil {
220+ f .Close ()
221+ }
222+ return syscall .Mount (node .Path , dest , "bind" , syscall .MS_BIND , "" )
223+ }
224+ return nil
225+ }
226+
227+ func mknodDevice (dest string , node * configs.Device ) error {
212228 fileMode := node .FileMode
213229 switch node .Type {
214230 case 'c' :
@@ -218,13 +234,10 @@ func createDeviceNode(rootfs string, node *configs.Device) error {
218234 default :
219235 return fmt .Errorf ("%c is not a valid device type for device %s" , node .Type , node .Path )
220236 }
221- if err := syscall .Mknod (dest , uint32 (fileMode ), node .Mkdev ()); err != nil && ! os .IsExist (err ) {
222- return fmt .Errorf ("mknod %s %s" , node .Path , err )
223- }
224- if err := syscall .Chown (dest , int (node .Uid ), int (node .Gid )); err != nil {
225- return fmt .Errorf ("chown %s to %d:%d" , node .Path , node .Uid , node .Gid )
237+ if err := syscall .Mknod (dest , uint32 (fileMode ), node .Mkdev ()); err != nil {
238+ return err
226239 }
227- return nil
240+ return syscall . Chown ( dest , int ( node . Uid ), int ( node . Gid ))
228241}
229242
230243func prepareRoot (config * configs.Config ) error {
@@ -251,16 +264,8 @@ func setupPtmx(config *configs.Config) error {
251264 return fmt .Errorf ("symlink dev ptmx %s" , err )
252265 }
253266 if config .Console != "" {
254- uid , err := config .HostUID ()
255- if err != nil {
256- return err
257- }
258- gid , err := config .HostGID ()
259- if err != nil {
260- return err
261- }
262267 console := newConsoleFromPath (config .Console )
263- return console .mount (config .Rootfs , config .MountLabel , uid , gid )
268+ return console .mount (config .Rootfs , config .MountLabel , 0 , 0 )
264269 }
265270 return nil
266271}
0 commit comments