Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0dd88a9

Browse files
authored
Merge branch 'main' into fix-poststart
2 parentsb7f2dab +ad5b481 commit0dd88a9

File tree

6 files changed

+107
-106
lines changed

6 files changed

+107
-106
lines changed

‎.github/workflows/validate.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ jobs:
4040
sudo apt -qy install libseccomp-dev
4141
-uses:golangci/golangci-lint-action@v6
4242
with:
43-
version:v1.57
43+
version:v1.59
4444
# Extra linters, only checking new code from a pull request.
4545
-name:lint-extra
4646
if:github.event_name == 'pull_request'

‎.golangci.yml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@ linters:
1111
-errorlint
1212
-unconvert
1313
-unparam
14+
15+
linters-settings:
16+
govet:
17+
enable:
18+
-nilness

‎libcontainer/container_linux.go‎

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func (c *Container) Status() (Status, error) {
9999
func (c*Container)State() (*State,error) {
100100
c.m.Lock()
101101
deferc.m.Unlock()
102-
returnc.currentState()
102+
returnc.currentState(),nil
103103
}
104104

105105
// OCIState returns the current container's state information.
@@ -531,7 +531,7 @@ func (c *Container) newParentProcess(p *Process) (parentProcess, error) {
531531
logrus.Debug("runc-dmz: using runc-dmz")// used for tests
532532
}elseiferrors.Is(err,dmz.ErrNoDmzBinary) {
533533
logrus.Debug("runc-dmz binary not embedded in runc binary, falling back to /proc/self/exe clone")
534-
}elseiferr!=nil{
534+
}else {
535535
returnnil,fmt.Errorf("failed to create runc-dmz binary clone: %w",err)
536536
}
537537
}else {
@@ -666,10 +666,7 @@ func (c *Container) newInitProcess(p *Process, cmd *exec.Cmd, comm *processComm)
666666

667667
func (c*Container)newSetnsProcess(p*Process,cmd*exec.Cmd,comm*processComm) (*setnsProcess,error) {
668668
cmd.Env=append(cmd.Env,"_LIBCONTAINER_INITTYPE="+string(initSetns))
669-
state,err:=c.currentState()
670-
iferr!=nil {
671-
returnnil,fmt.Errorf("unable to get container state: %w",err)
672-
}
669+
state:=c.currentState()
673670
// for setns process, we don't have to set cloneflags as the process namespaces
674671
// will only be set via setns syscall
675672
data,err:=c.bootstrapData(0,state.NamespacePaths)
@@ -847,12 +844,8 @@ func (c *Container) updateState(process parentProcess) (*State, error) {
847844
ifprocess!=nil {
848845
c.initProcess=process
849846
}
850-
state,err:=c.currentState()
851-
iferr!=nil {
852-
returnnil,err
853-
}
854-
err=c.saveState(state)
855-
iferr!=nil {
847+
state:=c.currentState()
848+
iferr:=c.saveState(state);err!=nil {
856849
returnnil,err
857850
}
858851
returnstate,nil
@@ -938,7 +931,7 @@ func (c *Container) isPaused() (bool, error) {
938931
returnstate==configs.Frozen,nil
939932
}
940933

941-
func (c*Container)currentState()(*State,error) {
934+
func (c*Container)currentState()*State {
942935
var (
943936
startTimeuint64
944937
externalDescriptors []string
@@ -982,7 +975,7 @@ func (c *Container) currentState() (*State, error) {
982975
}
983976
}
984977
}
985-
returnstate,nil
978+
returnstate
986979
}
987980

988981
func (c*Container)currentOCIState() (*specs.State,error) {

‎libcontainer/criu_linux.go‎

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -523,17 +523,7 @@ func (c *Container) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts) {
523523
// restore using CRIU. This function is inspired from the code in
524524
// rootfs_linux.go.
525525
func (c*Container)makeCriuRestoreMountpoints(m*configs.Mount)error {
526-
me:=mountEntry{Mount:m}
527-
dest,err:=securejoin.SecureJoin(c.config.Rootfs,m.Destination)
528-
iferr!=nil {
529-
returnerr
530-
}
531-
// TODO: pass srcFD? Not sure if criu is impacted by issue #2484.
532-
iferr:=checkProcMount(c.config.Rootfs,dest,me);err!=nil {
533-
returnerr
534-
}
535-
switchm.Device {
536-
case"cgroup":
526+
ifm.Device=="cgroup" {
537527
// No mount point(s) need to be created:
538528
//
539529
// * for v1, mount points are saved by CRIU because
@@ -542,23 +532,12 @@ func (c *Container) makeCriuRestoreMountpoints(m *configs.Mount) error {
542532
// * for v2, /sys/fs/cgroup is a real mount, but
543533
// the mountpoint appears as soon as /sys is mounted
544534
returnnil
545-
case"bind":
546-
// For bind-mounts (unlike other filesystem types), we need to check if
547-
// the source exists.
548-
fi,_,err:=me.srcStat()
549-
iferr!=nil {
550-
// error out if the source of a bind mount does not exist as we
551-
// will be unable to bind anything to it.
552-
returnerr
553-
}
554-
iferr:=createIfNotExists(dest,fi.IsDir());err!=nil {
555-
returnerr
556-
}
557-
default:
558-
// for all other filesystems just create the mountpoints
559-
iferr:=os.MkdirAll(dest,0o755);err!=nil {
560-
returnerr
561-
}
535+
}
536+
// TODO: pass srcFD? Not sure if criu is impacted by issue #2484.
537+
me:=mountEntry{Mount:m}
538+
// For all other filesystems, just make the target.
539+
if_,err:=createMountpoint(c.config.Rootfs,me);err!=nil {
540+
returnfmt.Errorf("create criu restore mountpoint for %s mount: %w",me.Destination,err)
562541
}
563542
returnnil
564543
}

‎libcontainer/rootfs_linux.go‎

Lines changed: 72 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,11 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
308308

309309
for_,b:=rangebinds {
310310
ifc.cgroupns {
311+
// We just created the tmpfs, and so we can just use filepath.Join
312+
// here (not to mention we want to make sure we create the path
313+
// inside the tmpfs, so we don't want to resolve symlinks).
311314
subsystemPath:=filepath.Join(c.root,b.Destination)
315+
subsystemName:=filepath.Base(b.Destination)
312316
iferr:=os.MkdirAll(subsystemPath,0o755);err!=nil {
313317
returnerr
314318
}
@@ -319,7 +323,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
319323
}
320324
var (
321325
source="cgroup"
322-
data=filepath.Base(subsystemPath)
326+
data=subsystemName
323327
)
324328
ifdata=="systemd" {
325329
data=cgroups.CgroupNamePrefix+data
@@ -349,14 +353,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error {
349353
}
350354

351355
funcmountCgroupV2(m*configs.Mount,c*mountConfig)error {
352-
dest,err:=securejoin.SecureJoin(c.root,m.Destination)
353-
iferr!=nil {
354-
returnerr
355-
}
356-
iferr:=os.MkdirAll(dest,0o755);err!=nil {
357-
returnerr
358-
}
359-
err=utils.WithProcfd(c.root,m.Destination,func(dstFdstring)error {
356+
err:=utils.WithProcfd(c.root,m.Destination,func(dstFdstring)error {
360357
returnmountViaFds(m.Source,nil,m.Destination,dstFd,"cgroup2",uintptr(m.Flags),m.Data)
361358
})
362359
iferr==nil||!(errors.Is(err,unix.EPERM)||errors.Is(err,unix.EBUSY)) {
@@ -482,6 +479,65 @@ func statfsToMountFlags(st unix.Statfs_t) int {
482479
returnflags
483480
}
484481

482+
varerrRootfsToFile=errors.New("config tries to change rootfs to file")
483+
484+
funccreateMountpoint(rootfsstring,mmountEntry) (string,error) {
485+
dest,err:=securejoin.SecureJoin(rootfs,m.Destination)
486+
iferr!=nil {
487+
return"",err
488+
}
489+
iferr:=checkProcMount(rootfs,dest,m);err!=nil {
490+
return"",fmt.Errorf("check proc-safety of %s mount: %w",m.Destination,err)
491+
}
492+
493+
switchm.Device {
494+
case"bind":
495+
fi,_,err:=m.srcStat()
496+
iferr!=nil {
497+
// Error out if the source of a bind mount does not exist as we
498+
// will be unable to bind anything to it.
499+
return"",err
500+
}
501+
// If the original source is not a directory, make the target a file.
502+
if!fi.IsDir() {
503+
// Make sure we aren't tricked into trying to make the root a file.
504+
ifrootfs==dest {
505+
return"",fmt.Errorf("%w: file bind mount over rootfs",errRootfsToFile)
506+
}
507+
// Make the parent directory.
508+
iferr:=os.MkdirAll(filepath.Dir(dest),0o755);err!=nil {
509+
return"",fmt.Errorf("make parent dir of file bind-mount: %w",err)
510+
}
511+
// Make the target file.
512+
f,err:=os.OpenFile(dest,os.O_CREATE,0o755)
513+
iferr!=nil {
514+
return"",fmt.Errorf("create target of file bind-mount: %w",err)
515+
}
516+
_=f.Close()
517+
// Nothing left to do.
518+
returndest,nil
519+
}
520+
521+
case"tmpfs":
522+
// If the original target exists, copy the mode for the tmpfs mount.
523+
ifstat,err:=os.Stat(dest);err==nil {
524+
dt:=fmt.Sprintf("mode=%04o",syscallMode(stat.Mode()))
525+
ifm.Data!="" {
526+
dt=dt+","+m.Data
527+
}
528+
m.Data=dt
529+
530+
// Nothing left to do.
531+
returndest,nil
532+
}
533+
}
534+
535+
iferr:=os.MkdirAll(dest,0o755);err!=nil {
536+
return"",err
537+
}
538+
returndest,nil
539+
}
540+
485541
funcmountToRootfs(c*mountConfig,mmountEntry)error {
486542
rootfs:=c.root
487543

@@ -495,7 +551,7 @@ func mountToRootfs(c *mountConfig, m mountEntry) error {
495551
// TODO: This won't be necessary once we switch to libpathrs and we can
496552
// stop all of these symlink-exchange attacks.
497553
dest:=filepath.Clean(m.Destination)
498-
if!strings.HasPrefix(dest,rootfs) {
554+
if!utils.IsLexicallyInRoot(rootfs,dest) {
499555
// Do not use securejoin as it resolves symlinks.
500556
dest=filepath.Join(rootfs,dest)
501557
}
@@ -516,37 +572,19 @@ func mountToRootfs(c *mountConfig, m mountEntry) error {
516572
returnmountPropagate(m,rootfs,"")
517573
}
518574

519-
mountLabel:=c.label
520-
dest,err:=securejoin.SecureJoin(rootfs,m.Destination)
575+
dest,err:=createMountpoint(rootfs,m)
521576
iferr!=nil {
522-
returnerr
523-
}
524-
iferr:=checkProcMount(rootfs,dest,m);err!=nil {
525-
returnerr
577+
returnfmt.Errorf("create mountpoint for %s mount: %w",m.Destination,err)
526578
}
579+
mountLabel:=c.label
527580

528581
switchm.Device {
529582
case"mqueue":
530-
iferr:=os.MkdirAll(dest,0o755);err!=nil {
531-
returnerr
532-
}
533583
iferr:=mountPropagate(m,rootfs,"");err!=nil {
534584
returnerr
535585
}
536586
returnlabel.SetFileLabel(dest,mountLabel)
537587
case"tmpfs":
538-
ifstat,err:=os.Stat(dest);err!=nil {
539-
iferr:=os.MkdirAll(dest,0o755);err!=nil {
540-
returnerr
541-
}
542-
}else {
543-
dt:=fmt.Sprintf("mode=%04o",syscallMode(stat.Mode()))
544-
ifm.Data!="" {
545-
dt=dt+","+m.Data
546-
}
547-
m.Data=dt
548-
}
549-
550588
ifm.Extensions&configs.EXT_COPYUP==configs.EXT_COPYUP {
551589
err=doTmpfsCopyUp(m,rootfs,mountLabel)
552590
}else {
@@ -555,15 +593,6 @@ func mountToRootfs(c *mountConfig, m mountEntry) error {
555593

556594
returnerr
557595
case"bind":
558-
fi,_,err:=m.srcStat()
559-
iferr!=nil {
560-
// error out if the source of a bind mount does not exist as we will be
561-
// unable to bind anything to it.
562-
returnerr
563-
}
564-
iferr:=createIfNotExists(dest,fi.IsDir());err!=nil {
565-
returnerr
566-
}
567596
// open_tree()-related shenanigans are all handled in mountViaFds.
568597
iferr:=mountPropagate(m,rootfs,mountLabel);err!=nil {
569598
returnerr
@@ -679,9 +708,6 @@ func mountToRootfs(c *mountConfig, m mountEntry) error {
679708
}
680709
returnmountCgroupV1(m.Mount,c)
681710
default:
682-
iferr:=os.MkdirAll(dest,0o755);err!=nil {
683-
returnerr
684-
}
685711
returnmountPropagate(m,rootfs,mountLabel)
686712
}
687713
}
@@ -899,6 +925,9 @@ func createDeviceNode(rootfs string, node *devices.Device, bind bool) error {
899925
iferr!=nil {
900926
returnerr
901927
}
928+
ifdest==rootfs {
929+
returnfmt.Errorf("%w: mknod over rootfs",errRootfsToFile)
930+
}
902931
iferr:=os.MkdirAll(filepath.Dir(dest),0o755);err!=nil {
903932
returnerr
904933
}
@@ -1169,26 +1198,6 @@ func chroot() error {
11691198
returnnil
11701199
}
11711200

1172-
// createIfNotExists creates a file or a directory only if it does not already exist.
1173-
funccreateIfNotExists(pathstring,isDirbool)error {
1174-
if_,err:=os.Stat(path);err!=nil {
1175-
ifos.IsNotExist(err) {
1176-
ifisDir {
1177-
returnos.MkdirAll(path,0o755)
1178-
}
1179-
iferr:=os.MkdirAll(filepath.Dir(path),0o755);err!=nil {
1180-
returnerr
1181-
}
1182-
f,err:=os.OpenFile(path,os.O_CREATE,0o755)
1183-
iferr!=nil {
1184-
returnerr
1185-
}
1186-
_=f.Close()
1187-
}
1188-
}
1189-
returnnil
1190-
}
1191-
11921201
// readonlyPath will make a path read only.
11931202
funcreadonlyPath(pathstring)error {
11941203
iferr:=mount(path,path,"",unix.MS_BIND|unix.MS_REC,"");err!=nil {

‎libcontainer/utils/utils_unix.go‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"path/filepath"
1010
"runtime"
1111
"strconv"
12+
"strings"
1213
"sync"
1314
_"unsafe"// for go:linkname
1415

@@ -260,3 +261,17 @@ func ProcThreadSelf(subpath string) (string, ProcThreadSelfCloser) {
260261
funcProcThreadSelfFd(fduintptr) (string,ProcThreadSelfCloser) {
261262
returnProcThreadSelf("fd/"+strconv.FormatUint(uint64(fd),10))
262263
}
264+
265+
// IsLexicallyInRoot is shorthand for strings.HasPrefix(path+"/", root+"/"),
266+
// but properly handling the case where path or root are "/".
267+
//
268+
// NOTE: The return value only make sense if the path doesn't contain "..".
269+
funcIsLexicallyInRoot(root,pathstring)bool {
270+
ifroot!="/" {
271+
root+="/"
272+
}
273+
ifpath!="/" {
274+
path+="/"
275+
}
276+
returnstrings.HasPrefix(path,root)
277+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp