From 449d114b475e20535610ee8eed8715fa8071f288 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Tue, 15 Mar 2011 00:45:45 +0000 Subject: [PATCH] Linux: Fix return codes from setpag Linux is a real stickler when it comes to error codes. Functions which return positive error codes into the kernel tend to have unfortunate effects. Because all AFS errors tend to be positive, most of our kernel entry points negate errors before passing them back to their caller. This causes problems when internal functions themselves return negative error codes. This was the case with the keyring functions, which ended up returning a negative code to setpag(), this handed that code ultimately up to the ioctl handler, which negated it (so turning it positive) before throwing it up to the kernel. The kernel sees this positive value as being a successful return, and so passes it direct to userland, rather than assigning it to errno. This led to the setpag() userspace function never being aware of keyring errors that had occurred in the kernel. Fix all this by making sure that all errors from the keyring code are made positive before being passed upwards in the kernel module. Reviewed-on: http://gerrit.openafs.org/4223 Tested-by: Marc Dionne Reviewed-by: Marc Dionne Tested-by: BuildBot Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear (cherry picked from commit 3d92852ba99bc7591515992dfea3436d93c23b85) Change-Id: I72177ad2ee6d0a2c2c3f6d6819289a761b2712f0 Reviewed-on: http://gerrit.openafs.org/4226 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/afs/LINUX/osi_groups.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/afs/LINUX/osi_groups.c b/src/afs/LINUX/osi_groups.c index 943c6b651..7561ecc37 100644 --- a/src/afs/LINUX/osi_groups.c +++ b/src/afs/LINUX/osi_groups.c @@ -168,6 +168,7 @@ __setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag, extern struct key_type key_type_keyring __attribute__((weak)); static struct key_type *__key_type_keyring = &key_type_keyring; +/* install_session_keyring returns negative error values */ static int install_session_keyring(struct key *keyring) { @@ -225,6 +226,12 @@ out: } #endif /* LINUX_KEYRING_SUPPORT */ +/* Error codes from setpag must be positive, otherwise they don't + * make it back into userspace properly. Error codes from the + * Linux keyring utilities, and from install_session_keyring() + * are negative. So we need to be careful to convert them correctly + * here + */ int setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag, int change_parent) @@ -255,6 +262,8 @@ setpag(cred_t **cr, afs_uint32 pagvalue, afs_uint32 *newpag, code = PTR_ERR(key); } } + if (code) + code = -code; } #endif /* LINUX_KEYRING_SUPPORT */ -- 2.39.5