Skip to content

Commit b276e7e

Browse files
committed
Fix SQLite volume lookup queries matching too liberally
Specifically, this does two things: 1. Turn on case-sensitive LIKE queries. Technically, this is not specific to volumes, as it will also affect container and pod lookups - but there, it only affects IDs. So `podman rm abc123` will not be the same as `podman rm ABC123` but I don't think anyone was manually entering uppercase SHA256 hash IDs so it shouldn't matter. 2. Escape the _ and % characters in volume lookup queries. These are SQLite wildcards, and meant that `podman volume rm test_1` would also match `podman volume rm testa2` (or any character in place of the underscore). This isn't done with pod and container lookups, but again those just use LIKE for IDs - so technically `podman volume rm abc_123` probably works and removes containers with an ID matching that pattern... I don't think that matters though. Fixes #26168 Signed-off-by: Matthew Heon <matthew.heon@pm.me>
1 parent e98e128 commit b276e7e

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

libpod/sqlite_state.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,16 @@ const (
3939
sqliteOptionForeignKeys = "&_foreign_keys=1"
4040
// Make sure that transactions happen exclusively.
4141
sqliteOptionTXLock = "&_txlock=exclusive"
42+
// Enforce case sensitivity for LIKE
43+
sqliteOptionCaseSensitiveLike = "&_cslike=TRUE"
4244

4345
// Assembled sqlite options used when opening the database.
4446
sqliteOptions = "db.sql?" +
4547
sqliteOptionLocation +
4648
sqliteOptionSynchronous +
4749
sqliteOptionForeignKeys +
48-
sqliteOptionTXLock
50+
sqliteOptionTXLock +
51+
sqliteOptionCaseSensitiveLike
4952
)
5053

5154
// NewSqliteState creates a new SQLite-backed state database.
@@ -2210,7 +2213,9 @@ func (s *SQLiteState) LookupVolume(name string) (*Volume, error) {
22102213
return nil, define.ErrDBClosed
22112214
}
22122215

2213-
rows, err := s.conn.Query("SELECT Name, JSON FROM VolumeConfig WHERE Name LIKE ? ORDER BY LENGTH(Name) ASC;", name+"%")
2216+
escaper := strings.NewReplacer("\\", "\\\\", "_", "\\_", "%", "\\%")
2217+
queryString := escaper.Replace(name) + "%"
2218+
rows, err := s.conn.Query("SELECT Name, JSON FROM VolumeConfig WHERE Name LIKE ? ESCAPE '\\' ORDER BY LENGTH(Name) ASC;", queryString)
22142219
if err != nil {
22152220
return nil, fmt.Errorf("querying database for volume %s: %w", name, err)
22162221
}

test/e2e/volume_rm_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,14 @@ var _ = Describe("Podman volume rm", func() {
114114
Expect(session).Should(ExitCleanly())
115115
Expect(len(session.OutputToStringArray())).To(BeNumerically(">=", 2))
116116
})
117+
118+
It("podman volume rm by unique partial name - case & underscore insensitive", func() {
119+
volNames := []string{"test_volume", "test-volume", "test", "Test"}
120+
for _, name := range volNames {
121+
podmanTest.PodmanExitCleanly("volume", "create", name)
122+
}
123+
124+
podmanTest.PodmanExitCleanly("volume", "rm", volNames[0])
125+
podmanTest.PodmanExitCleanly("volume", "rm", volNames[2])
126+
})
117127
})

0 commit comments

Comments
 (0)