| File: | sys/rmtsyss.c |
| Location: | line 73, column 5 |
| Description: | Access to field 'maxProcs' results in a dereference of a null pointer (loaded from variable 'service') |
| 1 | /* | ||||
| 2 | * Copyright 2000, International Business Machines Corporation and others. | ||||
| 3 | * All Rights Reserved. | ||||
| 4 | * | ||||
| 5 | * This software has been released under the terms of the IBM Public | ||||
| 6 | * License. For details, see the LICENSE file in the top-level source | ||||
| 7 | * directory or online at http://www.openafs.org/dl/license10.html | ||||
| 8 | */ | ||||
| 9 | |||||
| 10 | /* Daemon that implements remote procedure call service for non-vendor system | ||||
| 11 | * calls (currently setpag and pioctl). The AFS cache manager daemon, afsd, | ||||
| 12 | * currently fires up this module, when the "-rmtsys" flag is given. | ||||
| 13 | * This module resides in the lib/afs/librmtsys.a library. | ||||
| 14 | */ | ||||
| 15 | #include <afsconfig.h> | ||||
| 16 | #include <afs/param.h> | ||||
| 17 | |||||
| 18 | #include <roken.h> | ||||
| 19 | |||||
| 20 | #include <afs/vice.h> | ||||
| 21 | #include <rx/xdr.h> | ||||
| 22 | |||||
| 23 | /*#include <afs/cellconfig.h>*/ | ||||
| 24 | #include "rmtsys.h" | ||||
| 25 | #include "sys_prototypes.h" | ||||
| 26 | |||||
| 27 | #define NFS_EXPORTER1 1 /* To probably handle more later */ | ||||
| 28 | #define PSETPAG110 110 /* Also defined in afs/afs_pioctl.c */ | ||||
| 29 | #define PIOCTL_HEADER6 6 /* # of words prepended to special pioctl */ | ||||
| 30 | #define PSetClientContext99 99 /* Sets up caller's creds */ | ||||
| 31 | #define N_SECURITY_OBJECTS1 1 /* No real security yet */ | ||||
| 32 | |||||
| 33 | #define SETCLIENTCONTEXT(BLOB, host, uid, group0, group1, cmd, exportertype){ (BLOB)[0] = (host); (BLOB)[1] = (uid); (BLOB)[2] = (group0) ; (BLOB)[3] = (group1); (BLOB)[4] = (cmd); (BLOB)[5] = (exportertype ); } { \ | ||||
| 34 | (BLOB)[0] = (host); \ | ||||
| 35 | (BLOB)[1] = (uid); \ | ||||
| 36 | (BLOB)[2] = (group0); \ | ||||
| 37 | (BLOB)[3] = (group1); \ | ||||
| 38 | (BLOB)[4] = (cmd); \ | ||||
| 39 | (BLOB)[5] = (exportertype); \ | ||||
| 40 | } | ||||
| 41 | |||||
| 42 | |||||
| 43 | /* Main routine of the remote AFS system call server. The calling process will | ||||
| 44 | * never return; this is currently called from afsd (when "-rmtsys" is passed | ||||
| 45 | * as a parameter) */ | ||||
| 46 | void | ||||
| 47 | rmtsysd(void) | ||||
| 48 | { | ||||
| 49 | /* void catchsig(int); */ | ||||
| 50 | struct rx_securityClass *(securityObjects[N_SECURITY_OBJECTS1]); | ||||
| 51 | struct rx_service *service; | ||||
| 52 | |||||
| 53 | /* | ||||
| 54 | * Ignore SIGHUP signal since apparently is sent to the processes that | ||||
| 55 | * start up from /etc/rc for some systems like hpux and aix3.1... | ||||
| 56 | */ | ||||
| 57 | signal(SIGHUP1, SIG_IGN((__sighandler_t *)1)); | ||||
| 58 | |||||
| 59 | /* Initialize the rx-based RMTSYS server */ | ||||
| 60 | if (rx_Init(htons(AFSCONF_RMTSYSPORT)(__builtin_constant_p(7009) ? (__uint16_t)(((__uint16_t)(7009 )) << 8 | ((__uint16_t)(7009)) >> 8) : __bswap16_var (7009))) < 0) | ||||
| |||||
| 61 | rmt_Quit("rx_init"); | ||||
| 62 | securityObjects[0] = rxnull_NewServerSecurityObject(); | ||||
| 63 | if (securityObjects[0] == (struct rx_securityClass *)0) | ||||
| |||||
| 64 | rmt_Quit("rxnull_NewServerSecurityObject"); | ||||
| 65 | service = | ||||
| 66 | rx_NewService(0, RMTSYS_SERVICEID4, AFSCONF_RMTSYSSERVICE"afsrmtsys", | ||||
| 67 | securityObjects, N_SECURITY_OBJECTS1, | ||||
| 68 | RMTSYS_ExecuteRequest); | ||||
| 69 | if (service == NULL((void *)0)) | ||||
| |||||
| 70 | rmt_Quit("rx_NewService"); | ||||
| 71 | /* One may wish to tune some default RX params for better performance | ||||
| 72 | * at some point... */ | ||||
| 73 | rx_SetMaxProcs(service, 2)((service)->maxProcs = (2)); | ||||
| |||||
| 74 | rx_StartServer(1); /* Donate this process to the server process pool */ | ||||
| 75 | } | ||||
| 76 | |||||
| 77 | |||||
| 78 | /* Implements the remote setpag(2) call. Note that unlike the standard call, | ||||
| 79 | * here we also get back the new pag value; we need this so that the caller | ||||
| 80 | * can add it to its group list via setgroups() */ | ||||
| 81 | afs_int32 | ||||
| 82 | SRMTSYS_SetPag(struct rx_call *call, clientcred *creds, afs_int32 *newpag, | ||||
| 83 | afs_int32 *errornumber) | ||||
| 84 | { | ||||
| 85 | afs_uint32 blob[PIOCTL_HEADER6]; | ||||
| 86 | struct ViceIoctl data; | ||||
| 87 | afs_int32 error; | ||||
| 88 | |||||
| 89 | *errornumber = 0; | ||||
| 90 | SETCLIENTCONTEXT(blob, rx_HostOf(call->conn->peer), creds->uid,{ (blob)[0] = (((call->conn->peer)->host)); (blob)[1 ] = (creds->uid); (blob)[2] = (creds->group0); (blob)[3 ] = (creds->group1); (blob)[4] = (110); (blob)[5] = (1); } | ||||
| 91 | creds->group0, creds->group1, PSETPAG, NFS_EXPORTER){ (blob)[0] = (((call->conn->peer)->host)); (blob)[1 ] = (creds->uid); (blob)[2] = (creds->group0); (blob)[3 ] = (creds->group1); (blob)[4] = (110); (blob)[5] = (1); }; | ||||
| 92 | data.in = (caddr_t) blob; | ||||
| 93 | data.in_size = sizeof(blob); | ||||
| 94 | data.out = (caddr_t) blob; | ||||
| 95 | data.out_size = sizeof(blob); | ||||
| 96 | /* force local pioctl call */ | ||||
| 97 | error = lpioctl(0, _VICEIOCTL(PSetClientContext)((unsigned int) ((unsigned long) ((0x80000000) | (((sizeof(struct ViceIoctl)) & ((1 << 13) - 1)) << 16) | ((('V' )) << 8) | ((99))))), &data, 1); | ||||
| 98 | if (error) { | ||||
| 99 | if (errno(* __error()) == PSETPAG110) { | ||||
| 100 | *newpag = blob[0]; /* new pag value */ | ||||
| 101 | } else | ||||
| 102 | *errornumber = errno(* __error()); | ||||
| 103 | } | ||||
| 104 | return 0; | ||||
| 105 | } | ||||
| 106 | |||||
| 107 | |||||
| 108 | /* Implements the remote pioctl(2) call */ | ||||
| 109 | afs_int32 | ||||
| 110 | SRMTSYS_Pioctl(struct rx_call *call, clientcred *creds, char *path, | ||||
| 111 | afs_int32 cmd, afs_int32 follow, rmtbulk *InData, | ||||
| 112 | rmtbulk *OutData, afs_int32 *errornumber) | ||||
| 113 | { | ||||
| 114 | afs_int32 error; | ||||
| 115 | struct ViceIoctl data; | ||||
| 116 | char *pathp = path; | ||||
| 117 | afs_uint32 blob[PIOCTL_HEADER6]; | ||||
| 118 | |||||
| 119 | *errornumber = 0; | ||||
| 120 | SETCLIENTCONTEXT(blob, rx_HostOf(call->conn->peer), creds->uid,{ (blob)[0] = (((call->conn->peer)->host)); (blob)[1 ] = (creds->uid); (blob)[2] = (creds->group0); (blob)[3 ] = (creds->group1); (blob)[4] = (cmd); (blob)[5] = (1); } | ||||
| 121 | creds->group0, creds->group1, cmd, NFS_EXPORTER){ (blob)[0] = (((call->conn->peer)->host)); (blob)[1 ] = (creds->uid); (blob)[2] = (creds->group0); (blob)[3 ] = (creds->group1); (blob)[4] = (cmd); (blob)[5] = (1); }; | ||||
| 122 | data.in = | ||||
| 123 | (char *)malloc(InData->rmtbulk_len + | ||||
| 124 | PIOCTL_HEADER6 * sizeof(afs_int32)); | ||||
| 125 | if (!data.in) | ||||
| 126 | return (-1); /* helpless here */ | ||||
| 127 | if (!strcmp(path, NIL_PATHP"__FOO__")) | ||||
| 128 | pathp = (char *)0; /* It meant to be NIL */ | ||||
| 129 | memcpy(data.in, blob, sizeof(blob)); | ||||
| 130 | inparam_conversion(cmd, InData->rmtbulk_val, 1); | ||||
| 131 | memcpy(data.in + sizeof(blob), InData->rmtbulk_val, InData->rmtbulk_len); | ||||
| 132 | data.in_size = InData->rmtbulk_len + PIOCTL_HEADER6 * sizeof(afs_int32); | ||||
| 133 | data.out = OutData->rmtbulk_val; | ||||
| 134 | data.out_size = OutData->rmtbulk_len; | ||||
| 135 | /* force local pioctl call */ | ||||
| 136 | error = lpioctl(pathp, _VICEIOCTL(PSetClientContext)((unsigned int) ((unsigned long) ((0x80000000) | (((sizeof(struct ViceIoctl)) & ((1 << 13) - 1)) << 16) | ((('V' )) << 8) | ((99))))), &data, follow); | ||||
| 137 | if (error) { | ||||
| 138 | *errornumber = errno(* __error()); | ||||
| 139 | } else { | ||||
| 140 | /* Send the results back in network order */ | ||||
| 141 | outparam_conversion(cmd, data.out, 0); | ||||
| 142 | } | ||||
| 143 | free(data.in); | ||||
| 144 | /* Note that we return success (i.e. 0) even when pioctl fails; that's | ||||
| 145 | * because the actual errno is passed back via 'errornumber' and this call | ||||
| 146 | * MUST return success error in order to get that OUT params back (YUCK!) | ||||
| 147 | */ | ||||
| 148 | return (0); | ||||
| 149 | } | ||||
| 150 | |||||
| 151 | void | ||||
| 152 | rmt_Quit(char *msg, ...) | ||||
| 153 | { | ||||
| 154 | va_list ap; | ||||
| 155 | |||||
| 156 | va_start(ap, msg)__builtin_va_start((ap), (msg)); | ||||
| 157 | vfprintf(stderr__stderrp, msg, ap); | ||||
| 158 | va_end(ap)__builtin_va_end(ap); | ||||
| 159 | exit(1); | ||||
| 160 | } |