I have created a single linked list. Everything works fine.
I just want to know if I have done anything potentially dangerous in my code. The code snippets I am concern
It looks like you're on the right track, but there are issues. I would remove the global variables, and instead have a list_t struct (containing head and tail) that you pass into functions. As others have noted, you may also want to make the list generic by using (e.g.) a node_t type and void* data pointer.
Generally push and pop are used to refer to adding or removing an item at the beginning, not an arbitrary location (as you do); this is just a question of naming.
If you had product_name char *product_name instead, that would allow you to remove the length limitation as well as the need for strncpy. You would just have the caller allocate the string, and then free it in clean_up.
You could consider using a enum to improve your menu's readability. For "Check if this is in the first node - deleting from head" (same for tail), you should just compare head to product, not compare the codes.
After "tail = previous", you should set tail->next to NULL.