Exemplo n.º 1
0
func (overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool, error) {
	base := filepath.Base(path)
	dir := filepath.Dir(path)

	// if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay
	if base == WhiteoutOpaqueDir {
		if err := syscall.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0); err != nil {
			return false, err
		}

		// don't write the file itself
		return false, nil
	}

	// if a file was deleted and we are using overlay, we need to create a character device
	if strings.HasPrefix(base, WhiteoutPrefix) {
		originalBase := base[len(WhiteoutPrefix):]
		originalPath := filepath.Join(dir, originalBase)

		if err := syscall.Mknod(originalPath, syscall.S_IFCHR, 0); err != nil {
			return false, err
		}
		if err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil {
			return false, err
		}

		// don't write the file itself
		return false, nil
	}

	return true, nil
}
Exemplo n.º 2
0
// SetXAttr add an extended attribute to path with a write polciy specified
// in the flags parameter.
// The flags argument can be used to refine the semantics of the operation.
// XATTR_CREATE specifies a pure create, which fails if the named attribute
// exists already.
// XATTR_REPLACE specifies a pure replace operation, which fails if the named
// attribute does not already exist.
// By default (no flags), the extended attribute will be created if need be,
// or will simply replace the value if the attribute exists.
func SetXAttr(path, name string, val []byte, flags int) error {
	err := syscall.Setxattr(path, name, val, flags)
	if err != nil {
		return err
	}
	return nil
}
Exemplo n.º 3
0
// Associates name and data together as an attribute of path.
func Setxattr(path, name string, data []byte) error {
	name = userPrefix + name
	if err := syscall.Setxattr(path, name, data, 0); err != nil {
		return &XAttrError{"setxattr", path, name, err}
	}
	return nil
}
Exemplo n.º 4
0
func (constor *Constor) setdeleted(pathl string) error {
	stat := syscall.Stat_t{}
	err := syscall.Stat(pathl, &stat)
	if err != nil {
		fd, err := syscall.Creat(pathl, 0)
		if err != nil {
			return err
		}
		syscall.Close(fd)
	}
	return syscall.Setxattr(pathl, DELXATTR, []byte{49}, 0)
}
Exemplo n.º 5
0
func (a *FileAttr) WriteXAttr(p string) {
	if a.Attr == nil {
		return
	}

	var e EncodedAttr
	e.FromAttr(a.Attr)

	b := e.Encode(a.Hash)
	errno := syscall.Setxattr(p, _TERM_XATTR, b, 0)
	if errno != nil {
		log.Printf("Setxattr %s: code %v", p, errno)
	}
}
Exemplo n.º 6
0
func isXattrSupported() (result bool, err error) {
	result = true
	setXattrErr := syscall.Setxattr("/proc/self/exe", "user.test xattr", []byte("test xattr data"), 0)
	if setXattrErr != nil {
		errno := setXattrErr.(syscall.Errno)
		// syscall.Setxattr will return 'read-only filesystem' errors on a live-disc in live mode
		if errno == syscall.EOPNOTSUPP || errno == syscall.EROFS {
			result = false
		} else {
			err = setXattrErr
		}
	}
	return
}
Exemplo n.º 7
0
func (constor *Constor) createPath(dirpath string) error {
	dirs := strings.Split(dirpath, "/")
	if len(dirs) == 0 {
		return syscall.EIO
	}
	subdir := ""
	for _, dir := range dirs {
		if dir == "" {
			continue
		}
		subdir = Path.Join(subdir, "/", dir)
		li := constor.getLayer(subdir)
		if li == 0 {
			continue
		}
		if li == -1 {
			return syscall.EIO
		}
		stat := syscall.Stat_t{}
		if err := constor.Lstat(subdir, &stat); err != nil {
			return err
		}
		subdirl := Path.Join(constor.layers[0], subdir)
		if err := syscall.Mkdir(subdirl, stat.Mode); err != nil {
			return err
		}
		if err := syscall.Chown(subdirl, int(stat.Uid), int(stat.Gid)); err != nil {
			return err
		}
		if err := syscall.UtimesNano(subdirl, []syscall.Timespec{stat.Atim, stat.Mtim}); err != nil {
			return err
		}
		inoitoa := strconv.Itoa(int(stat.Ino))
		inobyte := []byte(inoitoa)
		if err := syscall.Setxattr(subdirl, INOXATTR, inobyte, 0); err != nil {
			return err
		}
		inode, err := constor.inodemap.findInode(stat.Ino)
		if err != nil {
			return err
		}
		inode.Lock()
		inode.layer = 0
		inode.Unlock()
	}
	return nil
}
Exemplo n.º 8
0
func setOrHasXattr(path, n, v string) error {
	if err := syscall.Setxattr(path, n, []byte(v), 1); err == nil {
		return nil
	} else if !os.IsExist(err) {
		return err
	}
	tab := make([]byte, 256)
	sz, err := syscall.Getxattr(path, n, tab)
	if err != nil {
		return err
	}
	if bytes.Equal([]byte(v), tab[:sz]) {
		return nil
	} else {
		return errors.New("XATTR mismatch")
	}
}
Exemplo n.º 9
0
func TestXAttrRead(t *testing.T) {
	nm := xattrFilename
	mountPoint, clean := xattrTestCase(t, nm)
	defer clean()

	mounted := filepath.Join(mountPoint, nm)
	attrs, err := listXAttr(mounted)
	readback := make(map[string][]byte)
	if err != nil {
		t.Error("Unexpected ListXAttr error", err)
	} else {
		for _, a := range attrs {
			val, err := readXAttr(mounted, a)
			if err != nil {
				t.Errorf("GetXAttr(%q) failed: %v", a, err)
			}
			readback[a] = val
		}
	}

	if len(readback) != len(xattrGolden) {
		t.Error("length mismatch", xattrGolden, readback)
	} else {
		for k, v := range readback {
			if bytes.Compare(xattrGolden[k], v) != 0 {
				t.Error("val mismatch", k, v, xattrGolden[k])
			}
		}
	}

	err = syscall.Setxattr(mounted, "third", []byte("value"), 0)
	if err != nil {
		t.Error("Setxattr error", err)
	}
	val, err := readXAttr(mounted, "third")
	if err != nil || string(val) != "value" {
		t.Error("Read back set xattr:", err, string(val))
	}

	syscall.Removexattr(mounted, "third")
	val, err = readXAttr(mounted, "third")
	if err != syscall.ENODATA {
		t.Error("Data not removed?", err, val)
	}
}
Exemplo n.º 10
0
func NewUidShiftingFilePermEditor(uidRange *user.UidRange) (FilePermissionsEditor, error) {
	if os.Geteuid() != 0 {
		return func(_ string, _, _ int, _ byte, _ os.FileInfo, _ map[string]string) error {
			// The files are owned by the current user on creation.
			// If we do nothing, they will remain so.
			return nil
		}, nil
	}

	return func(path string, uid, gid int, typ byte, fi os.FileInfo, xattr map[string]string) error {
		shiftedUid, shiftedGid, err := uidRange.ShiftRange(uint32(uid), uint32(gid))
		if err != nil {
			return err
		}
		if err := os.Lchown(path, int(shiftedUid), int(shiftedGid)); err != nil {
			return err
		}

		// lchown(2) says that, depending on the linux kernel version, it
		// can change the file's mode also if executed as root. So call
		// os.Chmod after it.
		if typ != tar.TypeSymlink {
			if err := os.Chmod(path, fi.Mode()); err != nil {
				return err
			}
		}

		if typ == tar.TypeReg || typ == tar.TypeRegA {
			for k, v := range xattr {
				if !isXattrAllowed(k) {
					continue
				}

				err := syscall.Setxattr(path, k, []byte(v), 0)
				if err != nil {
					return err
				}
			}
		}

		return nil
	}, nil
}
Exemplo n.º 11
0
func isXattrSupported() (bool, error) {
	var err error
	if xattrvar {
		LogWriter.Debug("Running forced xattr mode")
		return true, err
	}
	result := true
	setXattrErr := syscall.Setxattr("/proc/self/exe", "user.test xattr", []byte("test xattr data"), 0)
	if setXattrErr != nil {
		errno := setXattrErr.(syscall.Errno)
		// syscall.Setxattr will return 'read-only filesystem' errors on a live-disc in live mode
		if errno == syscall.EOPNOTSUPP || errno == syscall.EROFS {
			result = false
		} else {
			err = setXattrErr
		}
	}
	return result, err
}
Exemplo n.º 12
0
// based on libacl's acl_set_file
func setType(path, attr string, acl ACL) error {
	if attr == aclEADefault {
		fi, err := os.Stat(path)
		if err != nil {
			return err
		}

		// non-directories can't have default ACLs
		if !fi.IsDir() {
			return syscall.EACCES
		}
	}

	xattr, err := xattrFromACL(acl)
	if err != nil {
		return err
	}
	return syscall.Setxattr(path, attr, xattr, 0)
}
Exemplo n.º 13
0
func TestGetAllXattr(t *testing.T) {
	var (
		err       error
		testxattr = map[string]string{
			"user.checksum": "asdfsf13434qwf1324",
			"user.random":   "This is a test",
		}
	)
	xattrFile, err := ioutil.TempFile("", "")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.Remove(xattrFile.Name())
	xattrFile.Close()

	xattrDir, err := ioutil.TempDir("", "")
	if err != nil {
		t.Error(err)
		return
	}
	defer os.Remove(xattrDir)

	for k, v := range testxattr {
		err = syscall.Setxattr(xattrFile.Name(), k, []byte(v), 0)
		if err == syscall.ENOTSUP {
			t.Log(err)
			return
		}
		if err != nil {
			t.Error(err)
			return
		}
		err = syscall.Setxattr(xattrDir, k, []byte(v), 0)
		if err == syscall.ENOTSUP {
			t.Log(err)
			return
		}
		if err != nil {
			t.Error(err)
			return
		}
	}

	// Test retrieval of extended attributes for regular files.
	h, err := GetAllXattr(xattrFile.Name())
	if err != nil {
		t.Error(err)
		return
	}

	if h == nil {
		t.Errorf("Expected to find extended attributes but did not find any.")
		return
	}

	for k, v := range h {
		found, ok := h[k]
		if !ok || found != testxattr[k] {
			t.Errorf("Expected to find extended attribute %s with a value of %s on regular file but did not find it.", k, v)
			return
		}
	}

	// Test retrieval of extended attributes for directories.
	h, err = GetAllXattr(xattrDir)
	if err != nil {
		t.Error(err)
		return
	}

	if h == nil {
		t.Errorf("Expected to find extended attributes but did not find any.")
		return
	}

	for k, v := range h {
		found, ok := h[k]
		if !ok || found != testxattr[k] {
			t.Errorf("Expected to find extended attribute %s with a value of %s on directory but did not find it.", k, v)
			return
		}
	}
}
Exemplo n.º 14
0
func setWithXattr(path string, flags string) (err error) {
	err = syscall.Setxattr(path, "user.pax.flags", []byte(flags), 0)
	return
}
Exemplo n.º 15
0
// sets an attribute's value from bytes.
func (this *FileXattribsNS) Set(tag string, data []byte) error {
	return syscall.Setxattr(this.File.Name(), this.namespace+ssep+tag, data, 0)
}
Exemplo n.º 16
0
// Setxattr calls syscall setxattr
func Setxattr(path string, attr string, data []byte, flags int) (err error) {
	return syscall.Setxattr(path, attr, data, flags)
}
Exemplo n.º 17
0
func sysSetxattr(path string, attr string, val []byte, flag int) error {
	return syscall.Setxattr(path, attr, val, flag)
}
Exemplo n.º 18
0
func (fs *loopbackFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status {
	err := syscall.Setxattr(fs.GetPath(name), attr, data, flags)
	return fuse.ToStatus(err)
}
Exemplo n.º 19
0
func (b *Builder) createLayer(ids []string) (*ct.ImageLayer, error) {
	imageID := ids[len(ids)-1]

	layer, err := b.Store.Load(imageID)
	if err != nil {
		return nil, err
	} else if layer != nil {
		return layer, nil
	}

	// apply the docker layer diffs to a temporary directory
	dir, err := ioutil.TempDir("", "docker-layer-")
	if err != nil {
		return nil, err
	}
	defer os.RemoveAll(dir)
	for _, id := range ids {
		diff, err := b.Context.Diff(id, "")
		if err != nil {
			return nil, err
		}
		if err := archive.Untar(diff, dir, &archive.TarOptions{}); err != nil {
			return nil, err
		}

		// convert Docker AUFS whiteouts to overlay whiteouts.
		//
		// See the "whiteouts and opaque directories" section of the
		// OverlayFS documentation for a description of the whiteout
		// file formats:
		// https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt
		err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}
			if !info.Mode().IsRegular() {
				return nil
			}

			base := filepath.Base(path)
			dir := filepath.Dir(path)

			if base == archive.WhiteoutOpaqueDir {
				if err := syscall.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0); err != nil {
					return err
				}
				return os.Remove(path)
			}

			if !strings.HasPrefix(base, archive.WhiteoutPrefix) {
				return nil
			}

			// replace the file which the AUFS whiteout is hiding
			// with an overlay whiteout file, and remove the AUFS
			// whiteout
			name := filepath.Join(dir, strings.TrimPrefix(base, archive.WhiteoutPrefix))
			if err := os.RemoveAll(name); err != nil {
				return err
			}
			if err := syscall.Mknod(name, syscall.S_IFCHR, 0); err != nil {
				return err
			}
			stat := info.Sys().(*syscall.Stat_t)
			if err := os.Chown(name, int(stat.Uid), int(stat.Gid)); err != nil {
				return err
			}
			return os.Remove(path)
		})
		if err != nil {
			return nil, err
		}
	}

	// create the squashfs layer, with the root dir having 755 permissions
	if err := os.Chmod(dir, 0755); err != nil {
		return nil, err
	}
	path, layer, err := b.mksquashfs(dir)
	if err != nil {
		return nil, err
	}

	return layer, b.Store.Save(imageID, path, layer)
}
Exemplo n.º 20
0
func (w *RealFileWriter) SetAttr(n string, v []byte) error {
	err := syscall.Setxattr(w.path, n, v, 0)
	return err
}
Exemplo n.º 21
0
func setWithXattr(path string, flags string) error {
	flags = checkEmulTramp(flags)
	err := syscall.Setxattr(path, "user.pax.flags", []byte(flags), 0)
	return err
}
Exemplo n.º 22
0
func setxattr(path, key string, value []byte, flags int) error {
	return syscall.Setxattr(path, key, value, flags)
}