static int proc_sys_permission(struct inode *inode, int mask) { /* * sysctl entries that are not writeable, * are _NOT_ writeable, capabilities or not. */ struct ctl_table_header *head; struct ctl_table *table; int error; /* Executable files are not allowed under /proc/sys/ */ if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) return -EACCES; head = grab_header(inode); if (IS_ERR(head)) return PTR_ERR(head); table = PROC_I(inode)->sysctl_entry; if (!table) /* global root - r-xr-xr-x */ error = mask & MAY_WRITE ? -EACCES : 0; else /* Use the permissions on the sysctl table entry */ error = sysctl_perm(head->root, table, mask & ~MAY_NOT_BLOCK); sysctl_head_finish(head); return error; }
static unsigned int proc_sys_poll(struct file *filp, poll_table *wait) { struct inode *inode = filp->f_path.dentry->d_inode; struct ctl_table_header *head = grab_header(inode); struct ctl_table *table = PROC_I(inode)->sysctl_entry; unsigned int ret = DEFAULT_POLLMASK; unsigned long event; /* sysctl was unregistered */ if (IS_ERR(head)) return POLLERR | POLLHUP; if (!table->proc_handler) goto out; if (!table->poll) goto out; event = (unsigned long)filp->private_data; poll_wait(filp, &table->poll->wait, wait); if (event != atomic_read(&table->poll->event)) { filp->private_data = proc_sys_poll_event(table->poll); ret = POLLIN | POLLRDNORM | POLLERR | POLLPRI; } out: sysctl_head_finish(head); return ret; }
static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, size_t count, loff_t *ppos, int write) { struct inode *inode = filp->f_path.dentry->d_inode; struct ctl_table_header *head = grab_header(inode); struct ctl_table *table = PROC_I(inode)->sysctl_entry; ssize_t error; size_t res; if (IS_ERR(head)) return PTR_ERR(head); /* * At this point we know that the sysctl was not unregistered * and won't be until we finish. */ error = -EPERM; if (sysctl_perm(head->root, table, write ? MAY_WRITE : MAY_READ)) goto out; /* if that can happen at all, it should be -EINVAL, not -EISDIR */ error = -EINVAL; if (!table->proc_handler) goto out; /* careful: calling conventions are nasty here */ res = count; error = table->proc_handler(table, write, buf, &res, ppos); if (!error) error = res; out: sysctl_head_finish(head); return error; }
static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; struct ctl_table_header *head = grab_header(inode); struct ctl_table *table = PROC_I(inode)->sysctl_entry; struct ctl_table_header *h = NULL; unsigned long pos; int ret = -EINVAL; if (IS_ERR(head)) return PTR_ERR(head); if (table && !table->child) { WARN_ON(1); goto out; } table = table ? table->child : head->ctl_table; ret = 0; /* Avoid a switch here: arm builds fail with missing __cmpdi2 */ if (filp->f_pos == 0) { if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0) goto out; filp->f_pos++; } if (filp->f_pos == 1) { if (filldir(dirent, "..", 2, filp->f_pos, parent_ino(dentry), DT_DIR) < 0) goto out; filp->f_pos++; } pos = 2; ret = scan(head, table, &pos, filp, dirent, filldir); if (ret) goto out; for (h = sysctl_head_next(NULL); h; h = sysctl_head_next(h)) { if (h->attached_to != table) continue; ret = scan(h, h->attached_by, &pos, filp, dirent, filldir); if (ret) { sysctl_head_finish(h); break; } } ret = 1; out: sysctl_head_finish(head); return ret; }
static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct ctl_table_header *head = grab_header(dir); struct ctl_table *table = PROC_I(dir)->sysctl_entry; struct ctl_table_header *h = NULL; struct qstr *name = &dentry->d_name; struct ctl_table *p; struct inode *inode; struct dentry *err = ERR_PTR(-ENOENT); if (IS_ERR(head)) return ERR_CAST(head); if (table && !table->child) { WARN_ON(1); goto out; } table = table ? table->child : head->ctl_table; p = find_in_table(table, name); if (!p) { for (h = sysctl_head_next(NULL); h; h = sysctl_head_next(h)) { if (h->attached_to != table) continue; p = find_in_table(h->attached_by, name); if (p) break; } } if (!p) goto out; if (gr_handle_sysctl(p, MAY_EXEC)) goto out; err = ERR_PTR(-ENOMEM); inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p); if (h) sysctl_head_finish(h); if (!inode) goto out; err = NULL; d_set_d_op(dentry, &proc_sys_dentry_operations); d_add(dentry, inode); out: sysctl_head_finish(head); return err; }
static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode = dentry->d_inode; struct ctl_table_header *head = grab_header(inode); struct ctl_table *table = PROC_I(inode)->sysctl_entry; if (IS_ERR(head)) return PTR_ERR(head); generic_fillattr(inode, stat); if (table) stat->mode = (stat->mode & S_IFMT) | table->mode; sysctl_head_finish(head); return 0; }
static int proc_sys_open(struct inode *inode, struct file *filp) { struct ctl_table_header *head = grab_header(inode); struct ctl_table *table = PROC_I(inode)->sysctl_entry; /* sysctl was unregistered */ if (IS_ERR(head)) return PTR_ERR(head); if (table->poll) filp->private_data = proc_sys_poll_event(table->poll); sysctl_head_finish(head); return 0; }
static int proc_sys_permission(struct inode *inode, int mask) { /* * sysctl entries that are not writeable, * are _NOT_ writeable, capabilities or not. */ struct ctl_table_header *head = grab_header(inode); struct ctl_table *table = PROC_I(inode)->sysctl_entry; int error; if (IS_ERR(head)) return PTR_ERR(head); if (!table) /* global root - r-xr-xr-x */ error = mask & MAY_WRITE ? -EACCES : 0; else /* Use the permissions on the sysctl table entry */ error = sysctl_perm(head->root, table, mask); sysctl_head_finish(head); return error; }
/*------------------------------------------------------------------------------------------------------------------ -- FUNCTION: read_udp -- -- DATE: Febuary 6 2014 -- REVISIONS: none -- -- DESIGNER: Ramzi Chennafi -- PROGRAMMER: Ramzi Chennafi -- -- INTERFACE: int read_udp(HWND hwnd, WPARAM wParam, SOCKET sock) -- -- RETURNS: int, many return values, if the value is >= to 1 - it is assumed the transfer has ended. Otherwise it continues. -- -- NOTES: -- Interface for reading the UDP data and header. ----------------------------------------------------------------------------------------------------------------------*/ int read_udp(HWND hwnd, SOCKET sock){ if (SocketInfo->header_received == 0){ return grab_header(hwnd, sock); } return init_udp_receive(hwnd); }