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

[PATCH] n_r3964: Use struct pid to track user space clients

Currently this driver tracks user space clients it should send signals to. In
the presenct of file descriptor passing this is appears susceptible to
confusion from pid wrap around issues.

Replacing this with a struct pid prevents us from getting confused, and
prepares for a pid namespace implementation.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Eric W. Biederman and committed by
Linus Torvalds
3cec556a b3f13deb

+18 -21
+17 -20
drivers/char/n_r3964.c
··· 125 125 static void receive_char(struct r3964_info *pInfo, const unsigned char c); 126 126 static void receive_error(struct r3964_info *pInfo, const char flag); 127 127 static void on_timeout(unsigned long priv); 128 - static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg); 129 - static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char __user *buf); 128 + static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg); 129 + static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf); 130 130 static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg, 131 131 int error_code, struct r3964_block_header *pBlock); 132 132 static struct r3964_message* remove_msg(struct r3964_info *pInfo, ··· 829 829 } 830 830 831 831 static struct r3964_client_info *findClient( 832 - struct r3964_info *pInfo, pid_t pid) 832 + struct r3964_info *pInfo, struct pid *pid) 833 833 { 834 834 struct r3964_client_info *pClient; 835 835 ··· 843 843 return NULL; 844 844 } 845 845 846 - static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg) 846 + static int enable_signals(struct r3964_info *pInfo, struct pid *pid, int arg) 847 847 { 848 848 struct r3964_client_info *pClient; 849 849 struct r3964_client_info **ppClient; ··· 858 858 859 859 if(pClient->pid == pid) 860 860 { 861 - TRACE_PS("removing client %d from client list", pid); 861 + TRACE_PS("removing client %d from client list", pid_nr(pid)); 862 862 *ppClient = pClient->next; 863 863 while(pClient->msg_count) 864 864 { ··· 869 869 TRACE_M("enable_signals - msg kfree %p",pMsg); 870 870 } 871 871 } 872 + put_pid(pClient->pid); 872 873 kfree(pClient); 873 874 TRACE_M("enable_signals - kfree %p",pClient); 874 875 return 0; ··· 893 892 if(pClient==NULL) 894 893 return -ENOMEM; 895 894 896 - TRACE_PS("add client %d to client list", pid); 895 + TRACE_PS("add client %d to client list", pid_nr(pid)); 897 896 spin_lock_init(&pClient->lock); 898 897 pClient->sig_flags=arg; 899 - pClient->pid = pid; 898 + pClient->pid = get_pid(pid); 900 899 pClient->next=pInfo->firstClient; 901 900 pClient->first_msg = NULL; 902 901 pClient->last_msg = NULL; ··· 909 908 return 0; 910 909 } 911 910 912 - static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char __user *buf) 911 + static int read_telegram(struct r3964_info *pInfo, struct pid *pid, unsigned char __user *buf) 913 912 { 914 913 struct r3964_client_info *pClient; 915 914 struct r3964_block_header *block; ··· 1006 1005 /* Send SIGIO signal to client process: */ 1007 1006 if(pClient->sig_flags & R3964_USE_SIGIO) 1008 1007 { 1009 - kill_proc(pClient->pid, SIGIO, 1); 1008 + kill_pid(pClient->pid, SIGIO, 1); 1010 1009 } 1011 1010 } 1012 1011 ··· 1043 1042 { 1044 1043 struct r3964_block_header *block; 1045 1044 1046 - TRACE_PS("remove_client_block PID %d", pClient->pid); 1045 + TRACE_PS("remove_client_block PID %d", pid_nr(pClient->pid)); 1047 1046 1048 1047 block=pClient->next_block_to_read; 1049 1048 if(block) ··· 1158 1157 TRACE_M("r3964_close - msg kfree %p",pMsg); 1159 1158 } 1160 1159 } 1160 + put_pid(pClient->pid); 1161 1161 kfree(pClient); 1162 1162 TRACE_M("r3964_close - client kfree %p",pClient); 1163 1163 pClient=pNext; ··· 1195 1193 struct r3964_client_message theMsg; 1196 1194 DECLARE_WAITQUEUE (wait, current); 1197 1195 1198 - int pid = current->pid; 1199 1196 int count; 1200 1197 1201 1198 TRACE_L("read()"); 1202 1199 1203 - pClient=findClient(pInfo, pid); 1200 + pClient=findClient(pInfo, task_pid(current)); 1204 1201 if(pClient) 1205 1202 { 1206 1203 pMsg = remove_msg(pInfo, pClient); ··· 1253 1252 struct r3964_block_header *pHeader; 1254 1253 struct r3964_client_info *pClient; 1255 1254 unsigned char *new_data; 1256 - int pid; 1257 1255 1258 1256 TRACE_L("write request, %d characters", count); 1259 1257 /* ··· 1295 1295 pHeader->locks = 0; 1296 1296 pHeader->owner = NULL; 1297 1297 1298 - pid=current->pid; 1299 - 1300 - pClient=findClient(pInfo, pid); 1298 + pClient=findClient(pInfo, task_pid(current)); 1301 1299 if(pClient) 1302 1300 { 1303 1301 pHeader->owner = pClient; ··· 1326 1328 switch(cmd) 1327 1329 { 1328 1330 case R3964_ENABLE_SIGNALS: 1329 - return enable_signals(pInfo, current->pid, arg); 1331 + return enable_signals(pInfo, task_pid(current), arg); 1330 1332 case R3964_SETPRIORITY: 1331 1333 if(arg<R3964_MASTER || arg>R3964_SLAVE) 1332 1334 return -EINVAL; ··· 1339 1341 pInfo->flags &= ~R3964_BCC; 1340 1342 return 0; 1341 1343 case R3964_READ_TELEGRAM: 1342 - return read_telegram(pInfo, current->pid, (unsigned char __user *)arg); 1344 + return read_telegram(pInfo, task_pid(current), (unsigned char __user *)arg); 1343 1345 default: 1344 1346 return -ENOIOCTLCMD; 1345 1347 } ··· 1355 1357 struct poll_table_struct *wait) 1356 1358 { 1357 1359 struct r3964_info *pInfo=(struct r3964_info*)tty->disc_data; 1358 - int pid=current->pid; 1359 1360 struct r3964_client_info *pClient; 1360 1361 struct r3964_message *pMsg=NULL; 1361 1362 unsigned long flags; ··· 1362 1365 1363 1366 TRACE_L("POLL"); 1364 1367 1365 - pClient=findClient(pInfo,pid); 1368 + pClient=findClient(pInfo, task_pid(current)); 1366 1369 if(pClient) 1367 1370 { 1368 1371 poll_wait(file, &pInfo->read_wait, wait);
+1 -1
include/linux/n_r3964.h
··· 116 116 117 117 struct r3964_client_info { 118 118 spinlock_t lock; 119 - pid_t pid; 119 + struct pid *pid; 120 120 unsigned int sig_flags; 121 121 122 122 struct r3964_client_info *next;