Description
After upgrading from v1.10.1 to v1.12.0, Context.SaveUploadedFile started to fail when saving files directly into existing system directories like /tmp.
The failure happens due to an attempt to call os.Chmod on the target directory, even if it already exists and is not owned by the process.
Relevant code:
https://github.com/gin-gonic/gin/blob/v1.12.0/context.go#L734
Reproduction
file, _ := c.FormFile("file")
// Saving directly into /tmp
err := c.SaveUploadedFile(file, "/tmp/test.txt")
if err != nil {
panic(err)
}
Actual behavior
The call fails with:
chmod /tmp: operation not permitted
Expected behavior
If the directory already exists, especially for system directories like /tmp, SaveUploadedFile should not attempt to modify its permissions.
The previous behavior (v1.10.1) only used os.MkdirAll, which does not change permissions on existing directories.
Impact
This is a breaking change for common usage patterns such as:
- saving files to
/tmp/<filename>
- writing into pre-existing directories managed by the OS or container runtime
Context
This behavior appears to be introduced together with the change that allows specifying permissions for created directories (see #4068). However, applying chmod unconditionally also affects already existing directories.
Suggested fix
Only apply os.Chmod when the directory is newly created, or make it optional.
For example:
- skip
chmod if directory already exists
- or provide a flag to control this behavior
Additional notes
This change is not mentioned as breaking in release notes, but it alters previously working behavior.
Gin Version
v1.12.0
Can you reproduce the bug?
Yes
Source Code
file, _ := c.FormFile("file")
// Saving directly into /tmp
err := c.SaveUploadedFile(file, "/tmp/test.txt")
if err != nil {
panic(err)
}
Go Version
1.26.1
Operating System
linux
Description
After upgrading from v1.10.1 to v1.12.0,
Context.SaveUploadedFilestarted to fail when saving files directly into existing system directories like/tmp.The failure happens due to an attempt to call
os.Chmodon the target directory, even if it already exists and is not owned by the process.Relevant code:
https://github.com/gin-gonic/gin/blob/v1.12.0/context.go#L734
Reproduction
Actual behavior
The call fails with:
chmod /tmp: operation not permitted
Expected behavior
If the directory already exists, especially for system directories like
/tmp,SaveUploadedFileshould not attempt to modify its permissions.The previous behavior (v1.10.1) only used
os.MkdirAll, which does not change permissions on existing directories.Impact
This is a breaking change for common usage patterns such as:
/tmp/<filename>Context
This behavior appears to be introduced together with the change that allows specifying permissions for created directories (see #4068). However, applying
chmodunconditionally also affects already existing directories.Suggested fix
Only apply
os.Chmodwhen the directory is newly created, or make it optional.For example:
chmodif directory already existsAdditional notes
This change is not mentioned as breaking in release notes, but it alters previously working behavior.
Gin Version
v1.12.0
Can you reproduce the bug?
Yes
Source Code
Go Version
1.26.1
Operating System
linux