diff --git a/kbd/kbd.nm b/kbd/kbd.nm
index fbc57c7e6..af829cbc0 100644
--- a/kbd/kbd.nm
+++ b/kbd/kbd.nm
@@ -4,11 +4,11 @@
 ###############################################################################
 
 name       = kbd
-version    = 1.15.3
-release    = 2
+version    = 2.5.1
+release    = 1
 
 groups     = System/Base
-url        = http://ftp.altlinux.org/pub/people/legion/kbd
+url        = https://www.kbd-project.org/
 license    = GPLv2+
 summary    = Tools for configuring the console (keyboard, virtual terminals, etc.).
 
@@ -18,15 +18,17 @@ description
 	fonts, the virtual terminals and font files.
 end
 
-source_dl  =
+source_dl  = https://www.kernel.org/pub/linux/utils/kbd/
 sources   += kbd-latarcyrheb-16-fixed.tar.bz2
 sources   += kbd-latsun-fonts.tar.bz2
 
 build
 	requires
+		automake
 		bison
 		flex
 		gettext
+		pam-devel
 	end
 
 	configure_options += \
@@ -42,8 +44,6 @@ build
 
 		# 7-bit maps are obsolete; so are non-euro maps
 		cd %{DIR_APP}/data/keymaps/i386
-		mv qwerty/fi.map qwerty/fi-old.map
-		cp qwerty/fi-latin9.map qwerty/fi.map
 		cp qwerty/pt-latin9.map qwerty/pt.map
 		cp qwerty/sv-latin1.map qwerty/se-latin1.map
 		mv azerty/fr.map azerty/fr-old.map
@@ -51,7 +51,6 @@ build
 		cp azerty/fr-latin9.map azerty/fr-latin0.map
 
 		# Rename conflicting keymaps
-		mv dvorak/no.map dvorak/no-dvorak.map
 		mv fgGIod/trf.map fgGIod/trf-fgGIod.map
 		mv olpc/es.map olpc/es-olpc.map
 		mv olpc/pt.map olpc/pt-olpc.map
diff --git a/kbd/patches/kbd-1.15-defkeymap.patch b/kbd/patches/kbd-1.15-defkeymap.patch
deleted file mode 100644
index 5e604b71e..000000000
--- a/kbd/patches/kbd-1.15-defkeymap.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up kbd-1.15/src/paths.h.orig kbd-1.15/src/paths.h
---- kbd-1.15/src/paths.h.orig	2010-06-07 15:26:21.787315778 +0200
-+++ kbd-1.15/src/paths.h	2010-06-07 15:26:49.353336391 +0200
-@@ -19,7 +19,7 @@
- # define DEFMAP "sunkeymap.kmap"
- # define KERNDIR "/usr/src/linux/drivers/sbus/char"
- #else
--# define DEFMAP "defkeymap.kmap"
-+# define DEFMAP "defkeymap.map"
- # define KERNDIR "/usr/src/linux/drivers/char"
- #endif
- 
diff --git a/kbd/patches/kbd-1.15-keycodes-man.patch b/kbd/patches/kbd-1.15-keycodes-man.patch
index d18a8c8b5..e400c9df6 100644
--- a/kbd/patches/kbd-1.15-keycodes-man.patch
+++ b/kbd/patches/kbd-1.15-keycodes-man.patch
@@ -1,7 +1,7 @@
-diff -up kbd-1.15/man/man1/showkey.1_old kbd-1.15/man/man1/showkey.1
---- kbd-1.15/man/man1/showkey.1_old	2008-03-13 17:46:23.000000000 +0100
-+++ kbd-1.15/man/man1/showkey.1	2008-12-10 12:31:38.000000000 +0100
-@@ -80,6 +80,19 @@ corresponds to what the keyboard hardwar
+diff -up kbd-2.3.0/docs/man/man1/showkey.1.orig kbd-2.3.0/docs/man/man1/showkey.1
+--- kbd-2.3.0/docs/man/man1/showkey.1.orig	2020-07-08 19:25:47.000000000 +0200
++++ kbd-2.3.0/docs/man/man1/showkey.1	2020-07-16 08:56:15.970254183 +0200
+@@ -84,6 +84,19 @@ corresponds to what the keyboard hardwar
  to know the scan codes sent by various keys it is better to boot a
  2.4 kernel. Since 2.6.9 there also is the boot option atkbd.softraw=0
  that tells the 2.6 kernel to return the actual scan codes.
@@ -21,21 +21,21 @@ diff -up kbd-1.15/man/man1/showkey.1_old kbd-1.15/man/man1/showkey.1
  .SH "SEE ALSO"
  .BR loadkeys (1),
  .BR dumpkeys (1),
-diff -up kbd-1.15/man/man8/setkeycodes.8_old kbd-1.15/man/man8/setkeycodes.8
---- kbd-1.15/man/man8/setkeycodes.8_old	2008-12-10 12:31:56.000000000 +0100
-+++ kbd-1.15/man/man8/setkeycodes.8	2008-12-10 12:37:36.000000000 +0100
-@@ -41,6 +41,10 @@ to showkey(1), the command
- will assign the keycode 112 to it, and then loadkeys(1) can be used
- to define the function of this key.
- 
+diff -up kbd-2.3.0/docs/man/man8/setkeycodes.8.orig kbd-2.3.0/docs/man/man8/setkeycodes.8
+--- kbd-2.3.0/docs/man/man8/setkeycodes.8.orig	2020-07-08 19:35:35.000000000 +0200
++++ kbd-2.3.0/docs/man/man8/setkeycodes.8	2020-07-16 08:57:52.293900997 +0200
+@@ -42,6 +42,10 @@ the command
+ will assign the keycode 112 to it, and then
+ .BR loadkeys (1)
+ can be used to define the function of this key.
++
 +USB keyboards have standardized keycodes and
 +.B setkeycodes
 +doesn't affect them at all.
-+
- .SH "2.6 KERNELS"
- In 2.6 kernels key codes lie in the range 1-255, instead of 1-127.
- (It might be best to confine oneself to the range 1-239.)
-@@ -54,6 +58,14 @@ None.
+ .LP
+ Some older kernels might hardwire a low scancode range to the
+ equivalent keycodes; setkeycodes will fail when you try to remap
+@@ -60,6 +64,14 @@ None.
  .SH BUGS
  The keycodes of X have nothing to do with those of Linux.
  Unusual keys can be made visible under Linux, but not under X.
@@ -48,5 +48,5 @@ diff -up kbd-1.15/man/man8/setkeycodes.8_old kbd-1.15/man/man8/setkeycodes.8
 +cannot change the mapping of other devices than the "first" one.
 +
  .SH "SEE ALSO"
- .I "dumpkeys (1), loadkeys (1), showkey (1), getkeycodes (8)"
- 
+ .BR dumpkeys (1),
+ .BR loadkeys (1),
diff --git a/kbd/patches/kbd-1.15-resizecon-x86_64.patch b/kbd/patches/kbd-1.15-resizecon-x86_64.patch
deleted file mode 100644
index 5e8350a86..000000000
--- a/kbd/patches/kbd-1.15-resizecon-x86_64.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff -up kbd-1.15/configure_old kbd-1.15/configure
---- kbd-1.15/configure_old	2009-01-08 15:11:04.000000000 +0100
-+++ kbd-1.15/configure	2009-01-08 15:11:45.000000000 +0100
-@@ -7637,8 +7637,9 @@ fi
- 
- 
- case $host_cpu in
--	i?86*) RESIZECONS_PROGS=yes ;;
--	*)     RESIZECONS_PROGS=no ;;
-+	i?86*)   RESIZECONS_PROGS=yes ;;
-+	x86_64*) RESIZECONS_PROGS=yes ;;
-+	*)       RESIZECONS_PROGS=no ;;
- esac
-  if test "$RESIZECONS_PROGS" = "yes"; then
-   RESIZECONS_PROGS_TRUE=
diff --git a/kbd/patches/kbd-1.15-unicode_start.patch b/kbd/patches/kbd-1.15-unicode_start.patch
index 41827ccd4..119fe78d8 100644
--- a/kbd/patches/kbd-1.15-unicode_start.patch
+++ b/kbd/patches/kbd-1.15-unicode_start.patch
@@ -1,6 +1,6 @@
-diff -up kbd-1.15/src/unicode_start_old kbd-1.15/src/unicode_start
---- kbd-1.15/src/unicode_start_old	2009-01-08 13:34:10.000000000 +0100
-+++ kbd-1.15/src/unicode_start	2009-01-08 14:02:12.000000000 +0100
+diff -up kbd-1.15.2/src/unicode_start.orig kbd-1.15.2/src/unicode_start
+--- kbd-1.15.2/src/unicode_start.orig	2011-01-05 13:28:22.079662644 +0100
++++ kbd-1.15.2/src/unicode_start	2011-01-05 13:29:01.327353698 +0100
 @@ -72,6 +72,9 @@ stty iutf8
  # have a Unicode map attached, or explicitly specified, e.g.,
  # by giving `def.uni' as a second argument.
diff --git a/kbd/patches/kbd-1.15.3-dumpkeys-man.patch b/kbd/patches/kbd-1.15.3-dumpkeys-man.patch
deleted file mode 100644
index e77718b47..000000000
--- a/kbd/patches/kbd-1.15.3-dumpkeys-man.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff -up kbd-1.15.3/man/man1/dumpkeys.1.in.orig kbd-1.15.3/man/man1/dumpkeys.1.in
---- kbd-1.15.3/man/man1/dumpkeys.1.in.orig	2011-08-23 13:06:16.905892768 +0200
-+++ kbd-1.15.3/man/man1/dumpkeys.1.in	2011-08-23 13:15:18.264853435 +0200
-@@ -156,6 +156,14 @@ output of
- .BR dumpkeys .
- .LP
- .TP
-+.B \-1 \-\-separate-lines
-+This forces
-+.B dumpkeys
-+to write one line per (modifier,keycode) pair. It prefixes the word
-+.I plain
-+for plain keycodes.
-+.LP
-+.TP
- .B \-\-funcs-only
- When this option is given,
- .B dumpkeys
diff --git a/kbd/patches/kbd-1.15.3-fix-es-translation.patch b/kbd/patches/kbd-1.15.3-fix-es-translation.patch
deleted file mode 100644
index 9d43d8d15..000000000
--- a/kbd/patches/kbd-1.15.3-fix-es-translation.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up kbd-1.15.3/po/es.po.orig kbd-1.15.3/po/es.po
---- kbd-1.15.3/po/es.po.orig	2011-08-22 15:18:35.262343023 +0200
-+++ kbd-1.15.3/po/es.po	2011-08-22 15:19:14.844340262 +0200
-@@ -1363,7 +1363,7 @@ msgstr "No se encontró nada que guardar
- #: src/setfont.c:682
- #, c-format
- msgid "Saved %d-char %dx%d font file on %s\n"
--msgstr "Se ha guardado el fichero de tipos %2$dx%3$d de %1$d caracteres en %s\n"
-+msgstr "Se ha guardado el fichero de tipos %dx%d de %d caracteres en %s\n"
- 
- #: src/setkeycodes.c:21
- #, c-format
diff --git a/kbd/patches/kbd-1.15.5-loadkeys-search-path.patch b/kbd/patches/kbd-1.15.5-loadkeys-search-path.patch
new file mode 100644
index 000000000..16beb3da8
--- /dev/null
+++ b/kbd/patches/kbd-1.15.5-loadkeys-search-path.patch
@@ -0,0 +1,24 @@
+diff -up kbd-2.3.0/src/loadkeys.c.orig kbd-2.3.0/src/loadkeys.c
+--- kbd-2.3.0/src/loadkeys.c.orig	2020-06-02 12:16:45.000000000 +0200
++++ kbd-2.3.0/src/loadkeys.c	2020-07-16 09:02:50.398864688 +0200
+@@ -28,6 +28,8 @@
+ static const char *const dirpath1[] = {
+ 	"",
+ 	DATADIR "/" KEYMAPDIR "/**",
++	DATADIR "/" XKBKEYMAPDIR "/",
++	DATADIR "/" LEGACYKEYMAPDIR "/**",
+ 	KERNDIR "/",
+ 	NULL
+ };
+diff -up kbd-2.3.0/src/paths.h.orig kbd-2.3.0/src/paths.h
+--- kbd-2.3.0/src/paths.h.orig	2020-07-16 09:02:59.243010909 +0200
++++ kbd-2.3.0/src/paths.h	2020-07-16 09:03:23.446410942 +0200
+@@ -5,6 +5,8 @@
+  * The following five subdirectories are defined:
+  */
+ #define KEYMAPDIR "keymaps"
++#define XKBKEYMAPDIR "keymaps/xkb"
++#define LEGACYKEYMAPDIR "keymaps/legacy"
+ #define UNIMAPDIR "unimaps"
+ #define TRANSDIR "consoletrans"
+ #define VIDEOMODEDIR "videomodes"
diff --git a/kbd/patches/kbd-1.15.5-sg-decimal-separator.patch b/kbd/patches/kbd-1.15.5-sg-decimal-separator.patch
new file mode 100644
index 000000000..cb7398d57
--- /dev/null
+++ b/kbd/patches/kbd-1.15.5-sg-decimal-separator.patch
@@ -0,0 +1,12 @@
+diff -up kbd-1.15.5/data/keymaps/i386/qwertz/sg.map.orig kbd-1.15.5/data/keymaps/i386/qwertz/sg.map
+--- kbd-1.15.5/data/keymaps/i386/qwertz/sg.map.orig	2013-02-21 15:54:39.362799094 +0100
++++ kbd-1.15.5/data/keymaps/i386/qwertz/sg.map	2013-02-21 15:54:46.448838554 +0100
+@@ -1,7 +1,7 @@
+ keymaps 0-2,4-6,8,12
+ include "qwertz-layout"
+ include "linux-with-alt-and-altgr.inc"
+-	plain keycode  83 = KP_Comma
++	plain keycode  83 = KP_Period
+ strings as usual
+ 
+ keycode   1 = Escape           Escape
diff --git a/kbd/patches/kbd-2.0.2-unicode-start-font.patch b/kbd/patches/kbd-2.0.2-unicode-start-font.patch
new file mode 100644
index 000000000..72d47f40f
--- /dev/null
+++ b/kbd/patches/kbd-2.0.2-unicode-start-font.patch
@@ -0,0 +1,15 @@
+diff -up kbd-2.0.2/src/unicode_start.orig kbd-2.0.2/src/unicode_start
+--- kbd-2.0.2/src/unicode_start.orig	2014-08-12 14:47:53.019028849 +0200
++++ kbd-2.0.2/src/unicode_start	2014-08-12 14:54:42.631427602 +0200
+@@ -72,7 +72,10 @@ stty iutf8
+ # have a Unicode map attached, or explicitly specified, e.g.,
+ # by giving `def.uni' as a second argument.
+ 
+-DEFAULT_UNICODE_FONT=latarcyrheb-sun16
++# Source /etc/vconsole.conf to get default font
++. /etc/vconsole.conf
++
++DEFAULT_UNICODE_FONT=$FONT
+ # Also drdos8x16 is a good candidate.
+ 
+ case "$#" in
diff --git a/kbd/patches/kbd-2.4.0-covscan-fixes.patch b/kbd/patches/kbd-2.4.0-covscan-fixes.patch
new file mode 100644
index 000000000..c7ddf27b9
--- /dev/null
+++ b/kbd/patches/kbd-2.4.0-covscan-fixes.patch
@@ -0,0 +1,49 @@
+diff -up kbd-2.4.0/src/libkfont/psffontop.c.orig kbd-2.4.0/src/libkfont/psffontop.c
+--- kbd-2.4.0/src/libkfont/psffontop.c.orig	2020-04-27 17:53:01.000000000 +0200
++++ kbd-2.4.0/src/libkfont/psffontop.c	2021-04-27 09:59:14.170153676 +0200
+@@ -235,6 +235,7 @@ kfont_read_psffont(struct kfont_context
+ 
+ 		if (psfhdr->mode > PSF1_MAXMODE) {
+ 			KFONT_ERR(ctx, _("Unsupported psf file mode (%d)"), psfhdr->mode);
++			free(psfhdr);
+ 			return -EX_DATAERR;
+ 		}
+ 		fontlen   = ((psfhdr->mode & PSF1_MODE512) ? 512 : 256);
+@@ -251,6 +252,7 @@ kfont_read_psffont(struct kfont_context
+ 
+ 		if (psfhdr.version > PSF2_MAXVERSION) {
+ 			KFONT_ERR(ctx, _("Unsupported psf version (%d)"), psfhdr.version);
++			free(inputbuf);
+ 			return -EX_DATAERR;
+ 		}
+ 		fontlen   = assemble_uint32((unsigned char *)&psfhdr.length);
+@@ -260,16 +262,20 @@ kfont_read_psffont(struct kfont_context
+ 		ftoffset  = assemble_uint32((unsigned char *)&psfhdr.headersize);
+ 		fontwidth = assemble_uint32((unsigned char *)&psfhdr.width);
+ 		utf8      = 1;
+-	} else
++	} else {
++		free(inputbuf);
+ 		return -EX_DATAERR; /* not psf */
++	}
+ 
+ 	/* tests required - we divide by these */
+ 	if (fontlen == 0) {
+ 		KFONT_ERR(ctx, _("zero input font length?"));
++		free(inputbuf);
+ 		return -EX_DATAERR;
+ 	}
+ 	if (charsize == 0) {
+ 		KFONT_ERR(ctx, _("zero input character size?"));
++		free(inputbuf);
+ 		return -EX_DATAERR;
+ 	}
+ 
+@@ -277,6 +283,7 @@ kfont_read_psffont(struct kfont_context
+ 
+ 	if (i > inputlth || (!hastable && i != inputlth)) {
+ 		KFONT_ERR(ctx, _("Input file: bad input length (%d)"), inputlth);
++		free(inputbuf);
+ 		return -EX_DATAERR;
+ 	}
+ 
