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

NFSv4.1: Fix uninitialised variable in devicenotify

When decode_devicenotify_args() exits with no entries, we need to
ensure that the struct cb_devicenotifyargs is initialised to
{ 0, NULL } in order to avoid problems in
nfs4_callback_devicenotify().

Reported-by: <rtm@csail.mit.edu>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>

authored by

Trond Myklebust and committed by
Anna Schumaker
b05bf5c6 fbd2057e

+11 -11
+1 -1
fs/nfs/callback.h
··· 170 170 }; 171 171 172 172 struct cb_devicenotifyargs { 173 - int ndevs; 173 + uint32_t ndevs; 174 174 struct cb_devicenotifyitem *devs; 175 175 }; 176 176
+1 -1
fs/nfs/callback_proc.c
··· 358 358 struct cb_process_state *cps) 359 359 { 360 360 struct cb_devicenotifyargs *args = argp; 361 - int i; 361 + uint32_t i; 362 362 __be32 res = 0; 363 363 struct nfs_client *clp = cps->clp; 364 364 struct nfs_server *server = NULL;
+9 -9
fs/nfs/callback_xdr.c
··· 258 258 void *argp) 259 259 { 260 260 struct cb_devicenotifyargs *args = argp; 261 + uint32_t tmp, n, i; 261 262 __be32 *p; 262 263 __be32 status = 0; 263 - u32 tmp; 264 - int n, i; 265 - args->ndevs = 0; 266 264 267 265 /* Num of device notifications */ 268 266 p = xdr_inline_decode(xdr, sizeof(uint32_t)); ··· 269 271 goto out; 270 272 } 271 273 n = ntohl(*p++); 272 - if (n <= 0) 274 + if (n == 0) 273 275 goto out; 274 276 if (n > ULONG_MAX / sizeof(*args->devs)) { 275 277 status = htonl(NFS4ERR_BADXDR); ··· 328 330 dev->cbd_immediate = 0; 329 331 } 330 332 331 - args->ndevs++; 332 - 333 333 dprintk("%s: type %d layout 0x%x immediate %d\n", 334 334 __func__, dev->cbd_notify_type, dev->cbd_layout_type, 335 335 dev->cbd_immediate); 336 336 } 337 + args->ndevs = n; 338 + dprintk("%s: ndevs %d\n", __func__, args->ndevs); 339 + return 0; 340 + err: 341 + kfree(args->devs); 337 342 out: 343 + args->devs = NULL; 344 + args->ndevs = 0; 338 345 dprintk("%s: status %d ndevs %d\n", 339 346 __func__, ntohl(status), args->ndevs); 340 347 return status; 341 - err: 342 - kfree(args->devs); 343 - goto out; 344 348 } 345 349 346 350 static __be32 decode_sessionid(struct xdr_stream *xdr,