Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

target: fix PR state file path truncation

If an LIO backstore is configured with a sufficiently long Unit Serial
string, alongside a similarly long dbroot path, then a truncated
Persistent Reservation APTPL state file path will be used. This
truncation can unintentionally lead to two LUs with differing serial
numbers sharing PR state file.

Fixes: fdddf932269a ("target: use new "dbroot" target attribute")
Signed-off-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

authored by

David Disseldorp and committed by
Nicholas Bellinger
bdc79f0e 1ae01724

+7 -9
+7 -9
drivers/target/target_core_pr.c
··· 1973 1973 struct t10_wwn *wwn = &dev->t10_wwn; 1974 1974 struct file *file; 1975 1975 int flags = O_RDWR | O_CREAT | O_TRUNC; 1976 - char path[512]; 1976 + char *path; 1977 1977 u32 pr_aptpl_buf_len; 1978 1978 int ret; 1979 1979 loff_t pos = 0; 1980 1980 1981 - memset(path, 0, 512); 1981 + path = kasprintf(GFP_KERNEL, "%s/pr/aptpl_%s", db_root, 1982 + &wwn->unit_serial[0]); 1983 + if (!path) 1984 + return -ENOMEM; 1982 1985 1983 - if (strlen(&wwn->unit_serial[0]) >= 512) { 1984 - pr_err("WWN value for struct se_device does not fit" 1985 - " into path buffer\n"); 1986 - return -EMSGSIZE; 1987 - } 1988 - 1989 - snprintf(path, 512, "%s/pr/aptpl_%s", db_root, &wwn->unit_serial[0]); 1990 1986 file = filp_open(path, flags, 0600); 1991 1987 if (IS_ERR(file)) { 1992 1988 pr_err("filp_open(%s) for APTPL metadata" 1993 1989 " failed\n", path); 1990 + kfree(path); 1994 1991 return PTR_ERR(file); 1995 1992 } 1996 1993 ··· 1998 2001 if (ret < 0) 1999 2002 pr_debug("Error writing APTPL metadata file: %s\n", path); 2000 2003 fput(file); 2004 + kfree(path); 2001 2005 2002 2006 return (ret < 0) ? -EIO : 0; 2003 2007 }