diff --git a/.gitignore b/.gitignore
index e5ae55a..79c4020 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-SOURCES/grafana-7.5.10.tar.gz
-SOURCES/grafana-vendor-7.5.10-1.tar.xz
-SOURCES/grafana-webpack-7.5.10-1.tar.gz
+SOURCES/grafana-7.5.11.tar.gz
+SOURCES/grafana-vendor-7.5.11-1.tar.xz
+SOURCES/grafana-webpack-7.5.11-1.tar.gz
diff --git a/.grafana.metadata b/.grafana.metadata
index 03f3ec2..d33b818 100644
--- a/.grafana.metadata
+++ b/.grafana.metadata
@@ -1,3 +1,3 @@
-bb531789cb0dd0d3c9a2494a5924c64d12194d2f SOURCES/grafana-7.5.10.tar.gz
-804c0d639055608f3788ea84b6f94bca9fe8f1ca SOURCES/grafana-vendor-7.5.10-1.tar.xz
-8b52042f89703513945aa2086e5838cc425533c7 SOURCES/grafana-webpack-7.5.10-1.tar.gz
+cd7bfb63dd91361c1bc9c46d1f889b1f54f7758a SOURCES/grafana-7.5.11.tar.gz
+d55ac0b3a8fb3a0ce772442923e2ca3cba1af78f SOURCES/grafana-vendor-7.5.11-1.tar.xz
+db79c330e9a56dac2cdcae9b7c07c86112a66237 SOURCES/grafana-webpack-7.5.11-1.tar.gz
diff --git a/SOURCES/002-manpages.patch b/SOURCES/002-manpages.patch
index e87d709..36ca294 100644
--- a/SOURCES/002-manpages.patch
+++ b/SOURCES/002-manpages.patch
@@ -4,7 +4,7 @@ index 0000000000..7ac2af882c
 --- /dev/null
 +++ b/docs/man/man1/grafana-cli.1
 @@ -0,0 +1,60 @@
-+.TH GRAFANA "1" "September 2021" "Grafana cli version 7.5.10" "User Commands"
++.TH GRAFANA "1" "October 2021" "Grafana cli version 7.5.11" "User Commands"
 +.SH NAME
 +grafana-cli \- command line administration for the Grafana metrics dashboard and graph editor
 +.SH DESCRIPTION
@@ -70,7 +70,7 @@ index 0000000000..c616268b31
 --- /dev/null
 +++ b/docs/man/man1/grafana-server.1
 @@ -0,0 +1,72 @@
-+.TH VERSION "1" "September 2021" "Version 7.5.10" "User Commands"
++.TH VERSION "1" "October 2021" "Version 7.5.11" "User Commands"
 +.SH NAME
 +grafana-server \- back-end server for the Grafana metrics dashboard and graph editor
 +.SH DESCRIPTION
diff --git a/SOURCES/009-patch-unused-backend-crypto.patch b/SOURCES/009-patch-unused-backend-crypto.patch
new file mode 100644
index 0000000..12be571
--- /dev/null
+++ b/SOURCES/009-patch-unused-backend-crypto.patch
@@ -0,0 +1,168 @@
+diff --git a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
+new file mode 100644
+index 0000000..871e612
+--- /dev/null
++++ b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
+@@ -0,0 +1,25 @@
++package elgamal
++
++import (
++	"io"
++	"math/big"
++)
++
++// PublicKey represents an ElGamal public key.
++type PublicKey struct {
++	G, P, Y *big.Int
++}
++
++// PrivateKey represents an ElGamal private key.
++type PrivateKey struct {
++	PublicKey
++	X *big.Int
++}
++
++func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) {
++	panic("ElGamal encryption not available")
++}
++
++func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
++	panic("ElGamal encryption not available")
++}
+diff --git a/vendor/golang.org/x/crypto/openpgp/packet/packet.go b/vendor/golang.org/x/crypto/openpgp/packet/packet.go
+index 9728d61..9f04c2d 100644
+--- a/vendor/golang.org/x/crypto/openpgp/packet/packet.go
++++ b/vendor/golang.org/x/crypto/openpgp/packet/packet.go
+@@ -16,7 +16,6 @@ import (
+ 	"math/big"
+ 	"math/bits"
+ 
+-	"golang.org/x/crypto/cast5"
+ 	"golang.org/x/crypto/openpgp/errors"
+ )
+ 
+@@ -487,7 +486,7 @@ func (cipher CipherFunction) KeySize() int {
+ 	case Cipher3DES:
+ 		return 24
+ 	case CipherCAST5:
+-		return cast5.KeySize
++		panic("cast5 cipher not available")
+ 	case CipherAES128:
+ 		return 16
+ 	case CipherAES192:
+@@ -517,7 +516,7 @@ func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
+ 	case Cipher3DES:
+ 		block, _ = des.NewTripleDESCipher(key)
+ 	case CipherCAST5:
+-		block, _ = cast5.NewCipher(key)
++		panic("cast5 cipher not available")
+ 	case CipherAES128, CipherAES192, CipherAES256:
+ 		block, _ = aes.NewCipher(key)
+ 	}
+diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
+index 6126030..3a54c5f 100644
+--- a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
++++ b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
+@@ -5,13 +5,12 @@
+ package packet
+ 
+ import (
+-	"crypto/cipher"
+ 	"crypto/sha1"
+ 	"crypto/subtle"
+-	"golang.org/x/crypto/openpgp/errors"
+ 	"hash"
+ 	"io"
+-	"strconv"
++
++	"golang.org/x/crypto/openpgp/errors"
+ )
+ 
+ // SymmetricallyEncrypted represents a symmetrically encrypted byte string. The
+@@ -45,46 +44,7 @@ func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
+ // packet can be read. An incorrect key can, with high probability, be detected
+ // immediately and this will result in a KeyIncorrect error being returned.
+ func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) {
+-	keySize := c.KeySize()
+-	if keySize == 0 {
+-		return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(c)))
+-	}
+-	if len(key) != keySize {
+-		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
+-	}
+-
+-	if se.prefix == nil {
+-		se.prefix = make([]byte, c.blockSize()+2)
+-		_, err := readFull(se.contents, se.prefix)
+-		if err != nil {
+-			return nil, err
+-		}
+-	} else if len(se.prefix) != c.blockSize()+2 {
+-		return nil, errors.InvalidArgumentError("can't try ciphers with different block lengths")
+-	}
+-
+-	ocfbResync := OCFBResync
+-	if se.MDC {
+-		// MDC packets use a different form of OCFB mode.
+-		ocfbResync = OCFBNoResync
+-	}
+-
+-	s := NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync)
+-	if s == nil {
+-		return nil, errors.ErrKeyIncorrect
+-	}
+-
+-	plaintext := cipher.StreamReader{S: s, R: se.contents}
+-
+-	if se.MDC {
+-		// MDC packets have an embedded hash that we need to check.
+-		h := sha1.New()
+-		h.Write(se.prefix)
+-		return &seMDCReader{in: plaintext, h: h}, nil
+-	}
+-
+-	// Otherwise, we just need to wrap plaintext so that it's a valid ReadCloser.
+-	return seReader{plaintext}, nil
++	panic("OCFB cipher not available")
+ }
+ 
+ // seReader wraps an io.Reader with a no-op Close method.
+@@ -254,37 +214,5 @@ func (c noOpCloser) Close() error {
+ // written.
+ // If config is nil, sensible defaults will be used.
+ func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte, config *Config) (contents io.WriteCloser, err error) {
+-	if c.KeySize() != len(key) {
+-		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted.Serialize: bad key length")
+-	}
+-	writeCloser := noOpCloser{w}
+-	ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedMDC)
+-	if err != nil {
+-		return
+-	}
+-
+-	_, err = ciphertext.Write([]byte{symmetricallyEncryptedVersion})
+-	if err != nil {
+-		return
+-	}
+-
+-	block := c.new(key)
+-	blockSize := block.BlockSize()
+-	iv := make([]byte, blockSize)
+-	_, err = config.Random().Read(iv)
+-	if err != nil {
+-		return
+-	}
+-	s, prefix := NewOCFBEncrypter(block, iv, OCFBNoResync)
+-	_, err = ciphertext.Write(prefix)
+-	if err != nil {
+-		return
+-	}
+-	plaintext := cipher.StreamWriter{S: s, W: ciphertext}
+-
+-	h := sha1.New()
+-	h.Write(iv)
+-	h.Write(iv[blockSize-2:])
+-	contents = &seMDCWriter{w: plaintext, h: h}
+-	return
++	panic("OCFB cipher not available")
+ }
diff --git a/SOURCES/009-patch-unused-backend-crypto.vendor.patch b/SOURCES/009-patch-unused-backend-crypto.vendor.patch
deleted file mode 100644
index 12be571..0000000
--- a/SOURCES/009-patch-unused-backend-crypto.vendor.patch
+++ /dev/null
@@ -1,168 +0,0 @@
-diff --git a/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
-new file mode 100644
-index 0000000..871e612
---- /dev/null
-+++ b/vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go
-@@ -0,0 +1,25 @@
-+package elgamal
-+
-+import (
-+	"io"
-+	"math/big"
-+)
-+
-+// PublicKey represents an ElGamal public key.
-+type PublicKey struct {
-+	G, P, Y *big.Int
-+}
-+
-+// PrivateKey represents an ElGamal private key.
-+type PrivateKey struct {
-+	PublicKey
-+	X *big.Int
-+}
-+
-+func Encrypt(random io.Reader, pub *PublicKey, msg []byte) (c1, c2 *big.Int, err error) {
-+	panic("ElGamal encryption not available")
-+}
-+
-+func Decrypt(priv *PrivateKey, c1, c2 *big.Int) (msg []byte, err error) {
-+	panic("ElGamal encryption not available")
-+}
-diff --git a/vendor/golang.org/x/crypto/openpgp/packet/packet.go b/vendor/golang.org/x/crypto/openpgp/packet/packet.go
-index 9728d61..9f04c2d 100644
---- a/vendor/golang.org/x/crypto/openpgp/packet/packet.go
-+++ b/vendor/golang.org/x/crypto/openpgp/packet/packet.go
-@@ -16,7 +16,6 @@ import (
- 	"math/big"
- 	"math/bits"
- 
--	"golang.org/x/crypto/cast5"
- 	"golang.org/x/crypto/openpgp/errors"
- )
- 
-@@ -487,7 +486,7 @@ func (cipher CipherFunction) KeySize() int {
- 	case Cipher3DES:
- 		return 24
- 	case CipherCAST5:
--		return cast5.KeySize
-+		panic("cast5 cipher not available")
- 	case CipherAES128:
- 		return 16
- 	case CipherAES192:
-@@ -517,7 +516,7 @@ func (cipher CipherFunction) new(key []byte) (block cipher.Block) {
- 	case Cipher3DES:
- 		block, _ = des.NewTripleDESCipher(key)
- 	case CipherCAST5:
--		block, _ = cast5.NewCipher(key)
-+		panic("cast5 cipher not available")
- 	case CipherAES128, CipherAES192, CipherAES256:
- 		block, _ = aes.NewCipher(key)
- 	}
-diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
-index 6126030..3a54c5f 100644
---- a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
-+++ b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go
-@@ -5,13 +5,12 @@
- package packet
- 
- import (
--	"crypto/cipher"
- 	"crypto/sha1"
- 	"crypto/subtle"
--	"golang.org/x/crypto/openpgp/errors"
- 	"hash"
- 	"io"
--	"strconv"
-+
-+	"golang.org/x/crypto/openpgp/errors"
- )
- 
- // SymmetricallyEncrypted represents a symmetrically encrypted byte string. The
-@@ -45,46 +44,7 @@ func (se *SymmetricallyEncrypted) parse(r io.Reader) error {
- // packet can be read. An incorrect key can, with high probability, be detected
- // immediately and this will result in a KeyIncorrect error being returned.
- func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) {
--	keySize := c.KeySize()
--	if keySize == 0 {
--		return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(c)))
--	}
--	if len(key) != keySize {
--		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length")
--	}
--
--	if se.prefix == nil {
--		se.prefix = make([]byte, c.blockSize()+2)
--		_, err := readFull(se.contents, se.prefix)
--		if err != nil {
--			return nil, err
--		}
--	} else if len(se.prefix) != c.blockSize()+2 {
--		return nil, errors.InvalidArgumentError("can't try ciphers with different block lengths")
--	}
--
--	ocfbResync := OCFBResync
--	if se.MDC {
--		// MDC packets use a different form of OCFB mode.
--		ocfbResync = OCFBNoResync
--	}
--
--	s := NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync)
--	if s == nil {
--		return nil, errors.ErrKeyIncorrect
--	}
--
--	plaintext := cipher.StreamReader{S: s, R: se.contents}
--
--	if se.MDC {
--		// MDC packets have an embedded hash that we need to check.
--		h := sha1.New()
--		h.Write(se.prefix)
--		return &seMDCReader{in: plaintext, h: h}, nil
--	}
--
--	// Otherwise, we just need to wrap plaintext so that it's a valid ReadCloser.
--	return seReader{plaintext}, nil
-+	panic("OCFB cipher not available")
- }
- 
- // seReader wraps an io.Reader with a no-op Close method.
-@@ -254,37 +214,5 @@ func (c noOpCloser) Close() error {
- // written.
- // If config is nil, sensible defaults will be used.
- func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte, config *Config) (contents io.WriteCloser, err error) {
--	if c.KeySize() != len(key) {
--		return nil, errors.InvalidArgumentError("SymmetricallyEncrypted.Serialize: bad key length")
--	}
--	writeCloser := noOpCloser{w}
--	ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedMDC)
--	if err != nil {
--		return
--	}
--
--	_, err = ciphertext.Write([]byte{symmetricallyEncryptedVersion})
--	if err != nil {
--		return
--	}
--
--	block := c.new(key)
--	blockSize := block.BlockSize()
--	iv := make([]byte, blockSize)
--	_, err = config.Random().Read(iv)
--	if err != nil {
--		return
--	}
--	s, prefix := NewOCFBEncrypter(block, iv, OCFBNoResync)
--	_, err = ciphertext.Write(prefix)
--	if err != nil {
--		return
--	}
--	plaintext := cipher.StreamWriter{S: s, W: ciphertext}
--
--	h := sha1.New()
--	h.Write(iv)
--	h.Write(iv[blockSize-2:])
--	contents = &seMDCWriter{w: plaintext, h: h}
--	return
-+	panic("OCFB cipher not available")
- }
diff --git a/SOURCES/010-fips.cond.patch b/SOURCES/010-fips.cond.patch
deleted file mode 100644
index f9adee9..0000000
--- a/SOURCES/010-fips.cond.patch
+++ /dev/null
@@ -1,140 +0,0 @@
-diff --git a/vendor/golang.org/x/crypto/internal/boring/boring.go b/vendor/golang.org/x/crypto/internal/boring/boring.go
-new file mode 100644
-index 0000000..a9c550e
---- /dev/null
-+++ b/vendor/golang.org/x/crypto/internal/boring/boring.go
-@@ -0,0 +1,74 @@
-+// Copyright 2017 The Go Authors. All rights reserved.
-+// Copyright 2021 Red Hat.
-+// Use of this source code is governed by a BSD-style
-+// license that can be found in the LICENSE file.
-+
-+// +build linux
-+// +build !android
-+// +build !no_openssl
-+// +build !cmd_go_bootstrap
-+// +build !msan
-+
-+package boring
-+
-+// #include "openssl_pbkdf2.h"
-+// #cgo LDFLAGS: -ldl
-+import "C"
-+import (
-+	"bytes"
-+	"crypto/sha1"
-+	"crypto/sha256"
-+	"hash"
-+	"unsafe"
-+)
-+
-+var (
-+	emptySha1   = sha1.Sum([]byte{})
-+	emptySha256 = sha256.Sum256([]byte{})
-+)
-+
-+func hashToMD(h hash.Hash) *C.GO_EVP_MD {
-+	emptyHash := h.Sum([]byte{})
-+
-+	switch {
-+	case bytes.Equal(emptyHash, emptySha1[:]):
-+		return C._goboringcrypto_EVP_sha1()
-+	case bytes.Equal(emptyHash, emptySha256[:]):
-+		return C._goboringcrypto_EVP_sha256()
-+	}
-+	return nil
-+}
-+
-+// charptr returns the address of the underlying array in b,
-+// being careful not to panic when b has zero length.
-+func charptr(b []byte) *C.char {
-+	if len(b) == 0 {
-+		return nil
-+	}
-+	return (*C.char)(unsafe.Pointer(&b[0]))
-+}
-+
-+// ucharptr returns the address of the underlying array in b,
-+// being careful not to panic when b has zero length.
-+func ucharptr(b []byte) *C.uchar {
-+	if len(b) == 0 {
-+		return nil
-+	}
-+	return (*C.uchar)(unsafe.Pointer(&b[0]))
-+}
-+
-+func Pbkdf2Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
-+	// println("[debug] using pbkdf2 from OpenSSL")
-+	ch := h()
-+	md := hashToMD(ch)
-+	if md == nil {
-+		return nil
-+	}
-+
-+	out := make([]byte, keyLen)
-+	ok := C._goboringcrypto_PKCS5_PBKDF2_HMAC(charptr(password), C.int(len(password)), ucharptr(salt), C.int(len(salt)), C.int(iter), md, C.int(keyLen), ucharptr(out))
-+	if ok != 1 {
-+		panic("boringcrypto: PKCS5_PBKDF2_HMAC failed")
-+	}
-+	return out
-+}
-diff --git a/vendor/golang.org/x/crypto/internal/boring/notboring.go b/vendor/golang.org/x/crypto/internal/boring/notboring.go
-new file mode 100644
-index 0000000..e244fb5
---- /dev/null
-+++ b/vendor/golang.org/x/crypto/internal/boring/notboring.go
-@@ -0,0 +1,16 @@
-+// Copyright 2017 The Go Authors. All rights reserved.
-+// Copyright 2021 Red Hat.
-+// Use of this source code is governed by a BSD-style
-+// license that can be found in the LICENSE file.
-+
-+// +build !linux !cgo android cmd_go_bootstrap msan no_openssl
-+
-+package boring
-+
-+import (
-+	"hash"
-+)
-+
-+func Pbkdf2Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
-+	panic("boringcrypto: not available")
-+}
-diff --git a/vendor/golang.org/x/crypto/internal/boring/openssl_pbkdf2.h b/vendor/golang.org/x/crypto/internal/boring/openssl_pbkdf2.h
-new file mode 100644
-index 0000000..6dfdf10
---- /dev/null
-+++ b/vendor/golang.org/x/crypto/internal/boring/openssl_pbkdf2.h
-@@ -0,0 +1,5 @@
-+#include "/usr/lib/golang/src/crypto/internal/boring/goboringcrypto.h"
-+
-+DEFINEFUNC(int, PKCS5_PBKDF2_HMAC,
-+    (const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, EVP_MD *digest, int keylen, unsigned char *out),
-+    (pass, passlen, salt, saltlen, iter, digest, keylen, out))
-diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
-index 593f653..799a611 100644
---- a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
-+++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
-@@ -19,8 +19,11 @@ pbkdf2.Key.
- package pbkdf2 // import "golang.org/x/crypto/pbkdf2"
- 
- import (
-+	"crypto/boring"
- 	"crypto/hmac"
- 	"hash"
-+
-+	xboring "golang.org/x/crypto/internal/boring"
- )
- 
- // Key derives a key from the password, salt and iteration count, returning a
-@@ -40,6 +43,10 @@ import (
- // Using a higher iteration count will increase the cost of an exhaustive
- // search but will also make derivation proportionally slower.
- func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
-+	if boring.Enabled() {
-+		return xboring.Pbkdf2Key(password, salt, iter, keyLen, h)
-+	}
-+
- 	prf := hmac.New(h, password)
- 	hashLen := prf.Size()
- 	numBlocks := (keyLen + hashLen - 1) / hashLen
diff --git a/SOURCES/010-fips.patch b/SOURCES/010-fips.patch
new file mode 100644
index 0000000..f9adee9
--- /dev/null
+++ b/SOURCES/010-fips.patch
@@ -0,0 +1,140 @@
+diff --git a/vendor/golang.org/x/crypto/internal/boring/boring.go b/vendor/golang.org/x/crypto/internal/boring/boring.go
+new file mode 100644
+index 0000000..a9c550e
+--- /dev/null
++++ b/vendor/golang.org/x/crypto/internal/boring/boring.go
+@@ -0,0 +1,74 @@
++// Copyright 2017 The Go Authors. All rights reserved.
++// Copyright 2021 Red Hat.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// +build linux
++// +build !android
++// +build !no_openssl
++// +build !cmd_go_bootstrap
++// +build !msan
++
++package boring
++
++// #include "openssl_pbkdf2.h"
++// #cgo LDFLAGS: -ldl
++import "C"
++import (
++	"bytes"
++	"crypto/sha1"
++	"crypto/sha256"
++	"hash"
++	"unsafe"
++)
++
++var (
++	emptySha1   = sha1.Sum([]byte{})
++	emptySha256 = sha256.Sum256([]byte{})
++)
++
++func hashToMD(h hash.Hash) *C.GO_EVP_MD {
++	emptyHash := h.Sum([]byte{})
++
++	switch {
++	case bytes.Equal(emptyHash, emptySha1[:]):
++		return C._goboringcrypto_EVP_sha1()
++	case bytes.Equal(emptyHash, emptySha256[:]):
++		return C._goboringcrypto_EVP_sha256()
++	}
++	return nil
++}
++
++// charptr returns the address of the underlying array in b,
++// being careful not to panic when b has zero length.
++func charptr(b []byte) *C.char {
++	if len(b) == 0 {
++		return nil
++	}
++	return (*C.char)(unsafe.Pointer(&b[0]))
++}
++
++// ucharptr returns the address of the underlying array in b,
++// being careful not to panic when b has zero length.
++func ucharptr(b []byte) *C.uchar {
++	if len(b) == 0 {
++		return nil
++	}
++	return (*C.uchar)(unsafe.Pointer(&b[0]))
++}
++
++func Pbkdf2Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
++	// println("[debug] using pbkdf2 from OpenSSL")
++	ch := h()
++	md := hashToMD(ch)
++	if md == nil {
++		return nil
++	}
++
++	out := make([]byte, keyLen)
++	ok := C._goboringcrypto_PKCS5_PBKDF2_HMAC(charptr(password), C.int(len(password)), ucharptr(salt), C.int(len(salt)), C.int(iter), md, C.int(keyLen), ucharptr(out))
++	if ok != 1 {
++		panic("boringcrypto: PKCS5_PBKDF2_HMAC failed")
++	}
++	return out
++}
+diff --git a/vendor/golang.org/x/crypto/internal/boring/notboring.go b/vendor/golang.org/x/crypto/internal/boring/notboring.go
+new file mode 100644
+index 0000000..e244fb5
+--- /dev/null
++++ b/vendor/golang.org/x/crypto/internal/boring/notboring.go
+@@ -0,0 +1,16 @@
++// Copyright 2017 The Go Authors. All rights reserved.
++// Copyright 2021 Red Hat.
++// Use of this source code is governed by a BSD-style
++// license that can be found in the LICENSE file.
++
++// +build !linux !cgo android cmd_go_bootstrap msan no_openssl
++
++package boring
++
++import (
++	"hash"
++)
++
++func Pbkdf2Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
++	panic("boringcrypto: not available")
++}
+diff --git a/vendor/golang.org/x/crypto/internal/boring/openssl_pbkdf2.h b/vendor/golang.org/x/crypto/internal/boring/openssl_pbkdf2.h
+new file mode 100644
+index 0000000..6dfdf10
+--- /dev/null
++++ b/vendor/golang.org/x/crypto/internal/boring/openssl_pbkdf2.h
+@@ -0,0 +1,5 @@
++#include "/usr/lib/golang/src/crypto/internal/boring/goboringcrypto.h"
++
++DEFINEFUNC(int, PKCS5_PBKDF2_HMAC,
++    (const char *pass, int passlen, const unsigned char *salt, int saltlen, int iter, EVP_MD *digest, int keylen, unsigned char *out),
++    (pass, passlen, salt, saltlen, iter, digest, keylen, out))
+diff --git a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
+index 593f653..799a611 100644
+--- a/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
++++ b/vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go
+@@ -19,8 +19,11 @@ pbkdf2.Key.
+ package pbkdf2 // import "golang.org/x/crypto/pbkdf2"
+ 
+ import (
++	"crypto/boring"
+ 	"crypto/hmac"
+ 	"hash"
++
++	xboring "golang.org/x/crypto/internal/boring"
+ )
+ 
+ // Key derives a key from the password, salt and iteration count, returning a
+@@ -40,6 +43,10 @@ import (
+ // Using a higher iteration count will increase the cost of an exhaustive
+ // search but will also make derivation proportionally slower.
+ func Key(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
++	if boring.Enabled() {
++		return xboring.Pbkdf2Key(password, salt, iter, keyLen, h)
++	}
++
+ 	prf := hmac.New(h, password)
+ 	hashLen := prf.Size()
+ 	numBlocks := (keyLen + hashLen - 1) / hashLen
diff --git a/SOURCES/Makefile b/SOURCES/Makefile
index eff9c98..dab531d 100644
--- a/SOURCES/Makefile
+++ b/SOURCES/Makefile
@@ -8,10 +8,17 @@ SOURCE_TAR := $(NAME)-$(VERSION).tar.gz
 VENDOR_TAR := $(RPM_NAME)-vendor-$(VERSION)-$(RELEASE).tar.xz
 WEBPACK_TAR := $(RPM_NAME)-webpack-$(VERSION)-$(RELEASE).tar.gz
 
-ALL_PATCHES     := $(sort $(wildcard *.patch))
-VENDOR_PATCHES  := $(sort $(wildcard *.vendor.patch))
-COND_PATCHES    := $(sort $(wildcard *.cond.patch))
-REGULAR_PATCHES := $(filter-out $(VENDOR_PATCHES) $(COND_PATCHES),$(ALL_PATCHES))
+# patches which must be applied before creating the vendor tarball, for example:
+# - changes in dependency versions
+# - changes in Go module imports (which affect the vendored Go modules)
+PATCHES_PRE_VENDOR := \
+	005-remove-unused-dependencies.patch \
+	008-remove-unused-frontend-crypto.patch
+
+# patches which must be applied before creating the webpack, for example:
+# - changes in Node.js sources or vendored dependencies
+PATCHES_PRE_WEBPACK :=
+
 
 all: $(SOURCE_TAR) $(VENDOR_TAR) $(WEBPACK_TAR)
 
@@ -19,11 +26,12 @@ $(SOURCE_TAR):
 	spectool -g $(RPM_NAME).spec
 
 $(VENDOR_TAR): $(SOURCE_TAR)
+	# start with a clean state
 	rm -rf $(SOURCE_DIR)
 	tar xf $(SOURCE_TAR)
 
 	# Patches to apply before vendoring
-	for patch in $(REGULAR_PATCHES); do echo applying $$patch ...; patch -d $(SOURCE_DIR) -p1 --fuzz=0 < $$patch; done
+	for patch in $(PATCHES_PRE_VENDOR); do echo applying $$patch ...; patch -d $(SOURCE_DIR) -p1 --fuzz=0 < $$patch; done
 
 	# Go
 	cd $(SOURCE_DIR) && go mod vendor -v
@@ -46,15 +54,20 @@ $(VENDOR_TAR): $(SOURCE_TAR)
 	rm -r $(SOURCE_DIR)/node_modules/visjs-network/examples
 	./list_bundled_nodejs_packages.py $(SOURCE_DIR) >> $@.manifest
 
-	# Patches to apply after vendoring
-	for patch in $(VENDOR_PATCHES); do echo applying $$patch ...; patch -d $(SOURCE_DIR) -p1 --fuzz=0 < $$patch; done
-
 	# Create tarball
-	time XZ_OPT=-9 tar cJf $@ \
+	XZ_OPT=-9 time -p tar cJf $@ \
 		$(SOURCE_DIR)/vendor \
 		$$(find $(SOURCE_DIR) -type d -name "node_modules" -prune)
 
 $(WEBPACK_TAR): $(VENDOR_TAR)
+	# start with a clean state
+	rm -rf $(SOURCE_DIR)
+	tar xf $(SOURCE_TAR)
+	tar xf $(VENDOR_TAR)
+
+	# Patches to apply before creating the webpack
+	for patch in $(PATCHES_PRE_WEBPACK); do echo applying $$patch ...; patch -d $(SOURCE_DIR) -p1 --fuzz=0 < $$patch; done
+
 	cd $(SOURCE_DIR) && \
 		../build_frontend.sh
 
diff --git a/SPECS/grafana.spec b/SPECS/grafana.spec
index dee3dcf..d163399 100644
--- a/SPECS/grafana.spec
+++ b/SPECS/grafana.spec
@@ -29,7 +29,7 @@ end}
 %endif
 
 Name:             grafana
-Version:          7.5.10
+Version:          7.5.11
 Release:          1%{?dist}
 Summary:          Metrics dashboard and graph editor
 License:          ASL 2.0
@@ -85,11 +85,11 @@ Patch8:           008-remove-unused-frontend-crypto.patch
 # The Makefile removes a few files with crypto implementations
 # from the vendor tarball, which are not used in Grafana.
 # This patch removes all references to the deleted files.
-Patch9:           009-patch-unused-backend-crypto.vendor.patch
+Patch9:           009-patch-unused-backend-crypto.patch
 
 # This patch modifies the x/crypto/pbkdf2 function to use OpenSSL
 # if FIPS mode is enabled.
-Patch10:          010-fips.cond.patch
+Patch10:          010-fips.patch
 
 # Intersection of go_arches and nodejs_arches
 ExclusiveArch:    %{grafana_arches}
@@ -485,6 +485,7 @@ rm -r plugins-bundled
 %patch5 -p1
 %patch6 -p1
 %patch8 -p1
+%patch9 -p1
 %if %{enable_fips_mode}
 %patch10 -p1
 %endif
@@ -615,6 +616,10 @@ export GOPATH=%{_builddir}
 # let's set the time zone to a time zone without daylight saving time
 export TZ=GMT
 
+# GO111MODULE=on automatically skips vendored macaron sources in pkg/macaron
+# GO111MODULE=off doesn't skip them, and fails with an error due to the canoncial import path
+rm -r pkg/macaron
+
 %gotest ./pkg/...
 
 %if %{enable_fips_mode}
@@ -666,6 +671,10 @@ GOLANG_FIPS=1 go test -v ./pkg/util -run TestEncryption
 
 
 %changelog
+* Mon Oct 11 2021 Andreas Gerstmayr <agerstmayr@redhat.com> 7.5.11-1
+- update to 7.5.11 tagged upstream community sources, see CHANGELOG
+- resolve CVE-2021-39226
+
 * Thu Sep 30 2021 Andreas Gerstmayr <agerstmayr@redhat.com> 7.5.10-1
 - update to 7.5.10 tagged upstream community sources, see CHANGELOG