copy_to/form_user是否有必要

copy_to/from_user与put/get_user多做了什么?

unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
{
	if (likely(access_ok(VERIFY_WRITE, to, n)))
		n = __copy_to_user(to, from, n);
	return n;
}

以上函数都是linux内核推荐在内核中使用与用户空间交互的函数。那么为啥不能直接使用memcpy?

1.access_ok

在以上函数中都使用到了access_ok,而这个函数能够判断用户空间传入的地址是否来自用户空间(即不来自内核空间)

但是这个函数不能判断该地址是否为NULL/0,也就是说如果用户空间传入空指针,那么也是来自用户空间的

这避免了用户空间操作内核空间地址的可能性。

2.判断是否为野指针或者空指针

如果是那么就把改指针指向的地址值赋值为空,然后退出。这避免了内核Oops因为,如果在内核空间发生

Segmentation fault(段错误),那么会引起Oops,而如果是在用户空间发生段错误,那么内核会杀死这个进程。

但是同样会触发Segmentation fault。


总结:

1.阻止用户空间使用内核空间地址(如果用户进程在自己进程中访问内核地址会引发段错误,但是,不访问就不会出错,所以可以传给内核空间,进而内核空间要进行判断)

2.避免用户空间的段错误引起内核Oops或者Panic。(但是同样会利用段错误杀手用户进程)

我的实验:

内核空间:

ssize_t led_read(struct file *filp, char __user *buf, size_t size, loff_t *offset)
{
	char *data = "hello";
	if(!access_ok(VERIFY_WRITE,buf,strlen(data)))
		printk("access_not_ok\n",buf);
	printk("buf is %p",buf);
	//copy_to_user(buf, data, strlen(data));
	//printk("buf is %p\n",buf);
	memcpy(buf, data, strlen(data));
	return 0;
}

用户空间:

int main(int argc,char **argv)
{
	int fd = 0;
	char *data=0x9999999999999999999;
	if(argc!=2)
	{
		printf("argc error!\n");
		return -1;
	}
	fd = open(argv[1],O_RDWR);
	if(fd<0)
	{
		printf("open error!\n");
		return -1;
	}
	//*data = 1;
	//data = malloc(10*sizeof(char));
	read(fd,data,10);
	printf("buf is %p\n",data);
	printf("data is %s\n",data);
	//sleep(30);

	close(fd);
}
from django.contrib import admin from django.urls import reverse from django.utils.html import format_html from django.shortcuts import redirect from .models import Drug @admin.register(Drug) class DrugAdmin(admin.ModelAdmin): change_list_template = 'admin/drug/change_list.html' def get_urls(self): urls = super().get_urls() custom_urls = [ path('import-csv/', self.import_csv), ] return custom_urls + urls def import_csv(self, request): if request.method == 'POST': # TODO: import CSV data self.message_user(request, 'CSV data imported successfully') return redirect('..') return render(request, 'admin/drug/import_csv.html') def changelist_view(self, request, extra_context=None): if not request.GET.get('ordering'): # set default ordering request.GET = request.GET.copy() request.GET['ordering'] = 'name' return super().changelist_view(request, extra_context=extra_context) def interaction_display(self, obj): return format_html('<pre>{}</pre>', obj.interaction) interaction_display.short_description = 'Interaction' def get_actions(self, request): actions = super().get_actions(request) del actions['delete_selected'] return actions def delete_model(self, request, obj): # TODO: delete model pass def delete_selected(self, request, queryset): # TODO: delete selected models pass def get_queryset(self, request): qs = super().get_queryset(request) qs = qs.order_by('name') return qs def add_view(self, request, form_url='', extra_context=None): self.change_list_template = None return super().add_view(request, form_url=form_url, extra_context=extra_context) def change_view(self, request, object_id, form_url='', extra_context=None): self.change_list_template = None return super().change_view(request, object_id, form_url=form_url, extra_context=extra_context) def delete_view(self, request, object_id, extra_context=None): self.change_list_template = None return super().delete_view(request, object_id, extra_context=extra_context) 需要添加什么html文件
最新发布
05-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值